久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標(biāo)題:
自制MWC飛控2.3固件Arduino源碼
[打印本頁]
作者:
騰飛的龍
時間:
2019-1-14 15:19
標(biāo)題:
自制MWC飛控2.3固件Arduino源碼
好用的固件
0.png
(11.72 KB, 下載次數(shù): 68)
下載附件
2019-1-14 16:56 上傳
#include "Arduino.h"
#include "config.h"
#include "def.h"
#include "types.h"
#include "MultiWii.h"
#include "IMU.h"
#include "Sensors.h"
void getEstimatedAttitude();
void computeIMU () {
uint8_t axis;
static int16_t gyroADCprevious[3] = {0,0,0};
int16_t gyroADCp[3];
int16_t gyroADCinter[3];
static uint32_t timeInterleave = 0;
//we separate the 2 situations because reading gyro values with a gyro only setup can be acchieved at a higher rate
//gyro+nunchuk: we must wait for a quite high delay betwwen 2 reads to get both WM+ and Nunchuk data. It works with 3ms
//gyro only: the delay to read 2 consecutive values can be reduced to only 0.65ms
#if defined(NUNCHUCK)
annexCode();
while((uint16_t)(micros()-timeInterleave)<INTERLEAVING_DELAY) ; //interleaving delay between 2 consecutive reads
timeInterleave=micros();
ACC_getADC();
getEstimatedAttitude(); // computation time must last less than one interleaving delay
while((uint16_t)(micros()-timeInterleave)<INTERLEAVING_DELAY) ; //interleaving delay between 2 consecutive reads
timeInterleave=micros();
f.NUNCHUKDATA = 1;
while(f.NUNCHUKDATA) ACC_getADC(); // For this interleaving reading, we must have a gyro update at this point (less delay)
for (axis = 0; axis < 3; axis++) {
// empirical, we take a weighted value of the current and the previous values
// /4 is to average 4 values, note: overflow is not possible for WMP gyro here
imu.gyroData[axis] = (imu.gyroADC[axis]*3+gyroADCprevious[axis])>>2;
gyroADCprevious[axis] = imu.gyroADC[axis];
}
#else
#if ACC
ACC_getADC();
getEstimatedAttitude();
#endif
#if GYRO
Gyro_getADC();
#endif
for (axis = 0; axis < 3; axis++)
gyroADCp[axis] = imu.gyroADC[axis];
timeInterleave=micros();
annexCode();
uint8_t t=0;
while((uint16_t)(micros()-timeInterleave)<650) t=1; //empirical, interleaving delay between 2 consecutive reads
if (!t) annex650_overrun_count++;
#if GYRO
Gyro_getADC();
#endif
for (axis = 0; axis < 3; axis++) {
gyroADCinter[axis] = imu.gyroADC[axis]+gyroADCp[axis];
// empirical, we take a weighted value of the current and the previous values
imu.gyroData[axis] = (gyroADCinter[axis]+gyroADCprevious[axis])/3;
gyroADCprevious[axis] = gyroADCinter[axis]>>1;
if (!ACC) imu.accADC[axis]=0;
}
#endif
#if defined(GYRO_SMOOTHING)
static int16_t gyroSmooth[3] = {0,0,0};
for (axis = 0; axis < 3; axis++) {
imu.gyroData[axis] = (int16_t) ( ( (int32_t)((int32_t)gyroSmooth[axis] * (conf.Smoothing[axis]-1) )+imu.gyroData[axis]+1 ) / conf.Smoothing[axis]);
gyroSmooth[axis] = imu.gyroData[axis];
}
#elif defined(TRI)
static int16_t gyroYawSmooth = 0;
imu.gyroData[YAW] = (gyroYawSmooth*2+imu.gyroData[YAW])/3;
gyroYawSmooth = imu.gyroData[YAW];
#endif
}
// **************************************************
// Simplified IMU based on "Complementary Filter"
// Inspired by http://starlino.com/imu_guide.html
//
// adapted by ziss_dm : http://www.multiwii.com/forum/viewtopic.php?f=8&t=198
//
// The following ideas was used in this project:
// 1) Rotation matrix: http://en.wikipedia.org/wiki/Rotation_matrix
// 2) Small-angle approximation: http://en.wikipedia.org/wiki/Small-angle_approximation
// 3) C. Hastings approximation for atan2()
// 4) Optimization tricks: http://www.hackersdelight.org/
//
// Currently Magnetometer uses separate CF which is used only
// for heading approximation.
//
// **************************************************
//****** advanced users settings *******************
/* Set the Low Pass Filter factor for ACC
Increasing this value would reduce ACC noise (visible in GUI), but would increase ACC lag time
Comment this if you do not want filter at all.
unit = n power of 2 */
// this one is also used for ALT HOLD calculation, should not be changed
#ifndef ACC_LPF_FACTOR
#define ACC_LPF_FACTOR 4 // that means a LPF of 16
#endif
/* Set the Gyro Weight for Gyro/Acc complementary filter
Increasing this value would reduce and delay Acc influence on the output of the filter*/
#ifndef GYR_CMPF_FACTOR
#define GYR_CMPF_FACTOR 600
#endif
/* Set the Gyro Weight for Gyro/Magnetometer complementary filter
Increasing this value would reduce and delay Magnetometer influence on the output of the filter*/
#define GYR_CMPFM_FACTOR 250
//****** end of advanced users settings *************
#define INV_GYR_CMPF_FACTOR (1.0f / (GYR_CMPF_FACTOR + 1.0f))
#define INV_GYR_CMPFM_FACTOR (1.0f / (GYR_CMPFM_FACTOR + 1.0f))
typedef struct fp_vector {
float X,Y,Z;
} t_fp_vector_def;
typedef union {
float A[3];
t_fp_vector_def V;
} t_fp_vector;
typedef struct int32_t_vector {
int32_t X,Y,Z;
} t_int32_t_vector_def;
typedef union {
int32_t A[3];
t_int32_t_vector_def V;
} t_int32_t_vector;
int16_t _atan2(int32_t y, int32_t x){
float z = (float)y / x;
int16_t a;
if ( abs(y) < abs(x) ){
a = 573 * z / (1.0f + 0.28f * z * z);
if (x<0) {
if (y<0) a -= 1800;
else a += 1800;
}
} else {
a = 900 - 573 * z / (z * z + 0.28f);
if (y<0) a -= 1800;
}
return a;
}
float InvSqrt (float x){
union{
int32_t i;
float f;
} conv;
conv.f = x;
conv.i = 0x5f3759df - (conv.i >> 1);
return 0.5f * conv.f * (3.0f - x * conv.f * conv.f);
}
// Rotate Estimated vector(s) with small angle approximation, according to the gyro data
void rotateV(struct fp_vector *v,float* delta) {
fp_vector v_tmp = *v;
v->Z -= delta[ROLL] * v_tmp.X + delta[PITCH] * v_tmp.Y;
v->X += delta[ROLL] * v_tmp.Z - delta[YAW] * v_tmp.Y;
v->Y += delta[PITCH] * v_tmp.Z + delta[YAW] * v_tmp.X;
}
static int32_t accLPF32[3] = {0, 0, 1};
static float invG; // 1/|G|
static t_fp_vector EstG;
static t_int32_t_vector EstG32;
#if MAG
static t_int32_t_vector EstM32;
static t_fp_vector EstM;
#endif
void getEstimatedAttitude(){
uint8_t axis;
int32_t accMag = 0;
float scale, deltaGyroAngle[3];
uint8_t validAcc;
static uint16_t previousT;
uint16_t currentT = micros();
scale = (currentT - previousT) * GYRO_SCALE; // GYRO_SCALE unit: radian/microsecond
previousT = currentT;
// Initialization
for (axis = 0; axis < 3; axis++) {
deltaGyroAngle[axis] = imu.gyroADC[axis] * scale; // radian
accLPF32[axis] -= accLPF32[axis]>>ACC_LPF_FACTOR;
accLPF32[axis] += imu.accADC[axis];
imu.accSmooth[axis] = accLPF32[axis]>>ACC_LPF_FACTOR;
accMag += (int32_t)imu.accSmooth[axis]*imu.accSmooth[axis] ;
}
rotateV(&EstG.V,deltaGyroAngle);
#if MAG
rotateV(&EstM.V,deltaGyroAngle);
#endif
accMag = accMag*100/((int32_t)ACC_1G*ACC_1G);
validAcc = 72 < (uint16_t)accMag && (uint16_t)accMag < 133;
// Apply complimentary filter (Gyro drift correction)
// If accel magnitude >1.15G or <0.85G and ACC vector outside of the limit range => we neutralize the effect of accelerometers in the angle estimation.
// To do that, we just skip filter, as EstV already rotated by Gyro
for (axis = 0; axis < 3; axis++) {
if ( validAcc )
EstG.A[axis] = (EstG.A[axis] * GYR_CMPF_FACTOR + imu.accSmooth[axis]) * INV_GYR_CMPF_FACTOR;
EstG32.A[axis] = EstG.A[axis]; //int32_t cross calculation is a little bit faster than float
#if MAG
EstM.A[axis] = (EstM.A[axis] * GYR_CMPFM_FACTOR + imu.magADC[axis]) * INV_GYR_CMPFM_FACTOR;
EstM32.A[axis] = EstM.A[axis];
#endif
}
if ((int16_t)EstG32.A[2] > ACCZ_25deg)
f.SMALL_ANGLES_25 = 1;
else
f.SMALL_ANGLES_25 = 0;
// Attitude of the estimated vector
int32_t sqGX_sqGZ = sq(EstG32.V.X) + sq(EstG32.V.Z);
invG = InvSqrt(sqGX_sqGZ + sq(EstG32.V.Y));
att.angle[ROLL] = _atan2(EstG32.V.X , EstG32.V.Z);
att.angle[PITCH] = _atan2(EstG32.V.Y , InvSqrt(sqGX_sqGZ)*sqGX_sqGZ);
#if MAG
att.heading = _atan2(
EstM32.V.Z * EstG32.V.X - EstM32.V.X * EstG32.V.Z,
(EstM.V.Y * sqGX_sqGZ - (EstM32.V.X * EstG32.V.X + EstM32.V.Z * EstG32.V.Z) * EstG.V.Y)*invG );
att.heading += conf.mag_declination; // Set from GUI
att.heading /= 10;
#endif
#if defined(THROTTLE_ANGLE_CORRECTION)
cosZ = EstG.V.Z / ACC_1G * 100.0f; // cos(angleZ) * 100
throttleAngleCorrection = THROTTLE_ANGLE_CORRECTION * constrain(100 - cosZ, 0, 100) >>3; // 16 bit ok: 200*150 = 30000
#endif
}
#define UPDATE_INTERVAL 25000 // 40hz update rate (20hz LPF on acc)
#define BARO_TAB_SIZE 21
#define ACC_Z_DEADBAND (ACC_1G>>5) // was 40 instead of 32 now
#define applyDeadband(value, deadband) \
if(abs(value) < deadband) { \
value = 0; \
} else if(value > 0){ \
value -= deadband; \
} else if(value < 0){ \
value += deadband; \
}
#if BARO
uint8_t getEstimatedAltitude(){
int32_t BaroAlt;
static float baroGroundTemperatureScale,logBaroGroundPressureSum;
static float vel = 0.0f;
static uint16_t previousT;
uint16_t currentT = micros();
uint16_t dTime;
dTime = currentT - previousT;
if (dTime < UPDATE_INTERVAL) return 0;
previousT = currentT;
if(calibratingB > 0) {
logBaroGroundPressureSum = log(baroPressureSum);
baroGroundTemperatureScale = (baroTemperature + 27315) * 29.271267f;
calibratingB--;
}
// baroGroundPressureSum is not supposed to be 0 here
// see: https://code.google.com/p/ardupilot-mega/source/browse/libraries/AP_Baro/AP_Baro.cpp
BaroAlt = ( logBaroGroundPressureSum - log(baroPressureSum) ) * baroGroundTemperatureScale;
alt.EstAlt = (alt.EstAlt * 6 + BaroAlt * 2) >> 3; // additional LPF to reduce baro noise (faster by 30 ?s)
#if (defined(VARIOMETER) && (VARIOMETER != 2)) || !defined(SUPPRESS_BARO_ALTHOLD)
//P
int16_t error16 = constrain(AltHold - alt.EstAlt, -300, 300);
applyDeadband(error16, 10); //remove small P parametr to reduce noise near zero position
BaroPID = constrain((conf.pid[PIDALT].P8 * error16 >>7), -150, +150);
//I
errorAltitudeI += conf.pid[PIDALT].I8 * error16 >>6;
errorAltitudeI = constrain(errorAltitudeI,-30000,30000);
BaroPID += errorAltitudeI>>9; //I in range +/-60
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
全部資料51hei下載地址:
MultiWii.zip
(152.07 KB, 下載次數(shù): 62)
2019-1-14 15:19 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
ycb83523
時間:
2019-9-18 19:58
親,具體是怎么用呢?
作者:
騰飛的龍
時間:
2019-9-21 10:48
ycb83523 發(fā)表于 2019-9-18 19:58
親,具體是怎么用呢?
很簡單的飛控制作。
作者:
310139033
時間:
2019-11-9 17:16
謝謝分享,拿走了
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
亚洲 成人 在线
|
国产成视频在线观看
|
亚洲 欧美 综合
|
一二三区在线
|
91精品久久久久久久久久入口
|
免费久
|
欧美性网站
|
亚洲国产精品福利
|
久久久夜
|
欧美日韩一区二区三区在线观看
|
成人小视频在线观看
|
四虎在线观看
|
久久国产精品视频
|
中文精品视频
|
国产99久久精品一区二区永久免费
|
国产伦精品一区二区三区视频金莲
|
国产免费一区
|
91在线精品视频
|
亚洲欧美日韩精品久久亚洲区
|
中文字幕一区在线
|
在线观看国产视频
|
av中文字幕网
|
四虎成人在线播放
|
天堂中文资源在线
|
狠狠草视频
|
久久成人精品视频
|
成人久久18免费
|
久久久久久久久中文字幕
|
亚洲一区二区三区免费在线观看
|
国产精久久久久久
|
久久网一区二区
|
国产一区二区三区视频免费观看
|
国产东北一级毛片
|
91xh98hx 在线 国产
|
欧美一区二区在线观看
|
天天射影院
|
免费午夜视频在线观看
|
嫩草黄色影院
|
成人免费在线观看
|
亚洲 欧美 另类 综合 偷拍
|
中文字幕免费视频
|