BaseFlight Sensor - FabLabSeoul/WingProject GitHub Wiki
์ด ๊ธ์ ์คํ์์ค Multiwii Baseflight ๋ฅผ ๋ถ์ํ ๊ธ์ด๋ค.
Baseflight๋ ๊ฐ์์ผ์, ์์ด๋ก์ค์ฝํ, ์ง์๊ธฐ์ผ์๋ฅผ Sensor๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ๊ด๋ฆฌํ๋ค. ์ด 9 DOF๋ฅผ ์ฒ๋ฆฌํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค.
์์ ์์ค๋ STM32\stm32vldiscovery_package\Project\Examples\Sensor_Baseflight ๊ฒฝ๋ก์ ์๋ค. Baseflight Sensor๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํด MPU-6050๊ณผ HMC5883L ์ผ์๋ฅผ ํ ์คํธํ๋ ์์ ๋ค.
Sensor๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ดํดํ๊ธฐ ์ํด์ Baseflight์ ๊ธฐ๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ดํดํ๊ณ ์์ด์ผ ํ๋ค. ๊ธฐ๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- drv_system
- drv_gpio
- drv_usart
- drv_serial
- serial
- drv_hmc5883l
- drv_mpu5060
- drv_i2c
- printf
Sensor๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์์ ์ด๊ฑฐํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ชจ๋ ์ฐ๊ณ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ถ๊ฐ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- imu
- util
- sensor
์ด ๊ธ์์๋ ์ฃผ๋ก util, imu, sensor ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค๋ช ํ๊ณ , ์ ์ฒด ํ๋ฆ์ ์ค๋ช ํ๋๋ฐ ์ค์ ์ ๋๊ฒ ๋ค.
์ด๊ธฐํ
Sensor ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ธฐ์ํด ์ด๊ธฐํ ํ๋ ๊ณผ์ ์ ๋ณด์ฌ์ค๋ค.
void setup()
{
gpio_config_t gpio;
bool sensorsOK = false;
mcfg.emf_avoidance = 0;
mcfg.gyro_cmpf_factor = 600; // default MWC
mcfg.gyro_cmpfm_factor = 250; // default MWC
mcfg.gyro_lpf = 42; // supported by all gyro drivers now. In case of ST gyro, will default to 32Hz instead
mcfg.gyro_align = ALIGN_DEFAULT;
mcfg.acc_align = ALIGN_DEFAULT;
mcfg.mag_align = ALIGN_DEFAULT;
mcfg.vbatscale = 110;
mcfg.currentscale = 400; // for Allegro ACS758LCB-100U (40mV/A)
mcfg.moron_threshold = 32;
cfg.mag_declination = 0; // For example, -6deg 37min, = -637 Japan, format is [sign]dddmm (degreesminutes) default is zero.
cfg.small_angle = 25;
cfg.throttle_correction_value = 0; // could 10 with althold or 40 for fpv
cfg.throttle_correction_angle = 800; // could be 80.0 deg with atlhold or 45.0 for fpv
cfg.accz_lpf_cutoff = 5.0f;
cfg.acc_lpf_factor = 4;
cfg.accz_deadband = 40;
cfg.accxy_deadband = 40;
// RCC ์ด๊ธฐํ.
SystemInit();
// ํด๋ญ, ํ์ด๋จธ ์ด๊ธฐํ
systemInit();
// sleep for 100ms
delay(100);
// Stm32 ๋ณด๋์ ์๋ LED3,4๋ฅผ ํ์ฑํ ํ๋ค.
gpio.pin = Pin_All;
gpio.speed = Speed_2MHz;
gpio.mode = Mode_Out_PP;
gpioInit(GPIOC, &gpio);
// MPU-6050, HMC5883L๊ณผ ํต์ ํ i2c๋ฅผ ์ด๊ธฐํ ํ๋ค.
i2cInit(I2CDEV_1, 0x00); // Init Master i2c
// MPU-6050, HMC6553L ์ผ์ ์ฒดํฌ
// ์ผ์ ์ด๊ธฐํ.
sensorsOK = sensorsAutodetect();
// if gyro was not detected due to whatever reason, we give up now.
if (!sensorsOK)
failureMode(3);
// IMU ์ด๊ธฐํ
// ์ง์๊ธฐ ์ผ์ HMC6553L ์ด๊ธฐํ
imuInit();
// ์๋ฆฌ์ผ ํต์ ์ด๊ธฐํ.
// PA10,9 (Rx,Tx)
serialInit(115200);
}
๋จผ์ ์ ์ญ์ ์ผ๋ก ํ์ํ ์ ๋ณด๋ค์ master_t
๊ตฌ์กฐ์ฒด์ config_t
๊ตฌ์กฐ์ฒด์ ๊ฐ๊ฐ ์ ์ญ๋ณ์ mcfg
, cfg
๋ฅผ ์ด๊ธฐํ ํ๋ค. ํ์ฌ Sensor ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํ์ํ ๊ฐ๋ค๋ง ์ด๊ธฐํ ํ๋ค.
delay()
ํจ์๋ฅผ ์ฌ์ฉํ๊ธฐ์ํด Baseflightํจ์ systeminit()
๋ฅผ ๋จผ์ ํธ์ถํด์ผ ํ๋ค. ๊ทธ๋ฆฌ๊ณ Stm32 value line discovery ๋ณด๋์ LED3,4 ๋ฅผ ์ฌ์ฉํ๊ธฐ์ํด GPIOC๋ฅผ ํ์ฑํ ํ๋ค.
์ผ์์ ํต์ ์ ์ํด I2C๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ i2cInit(I2CDEV_1, 0x00);
ํจ์๋ฅผ ์ด์ฉํด ์ด๊ธฐํ ํ๋ค. ์ฒซ ๋ฒ์งธ I2C ์ฅ์น๋ฅผ ์ด์ฉํ๊ณ , ๋ง์คํฐ๊ฐ ๋๊ธฐ ๋๋ฌธ์ ์ฃผ์๊ฐ์ ํ์์์ผ๋ฏ๋ก 0x00
์ผ๋ก ์ค์ ํ๋ค.
์ฌ๊ธฐ๊น์ง ์งํ๋์๋ค๋ฉด, ๋ณธ๊ฒฉ์ ์ผ๋ก ์ผ์์ ํต์ ์ ์์ํ๋ค. sensorsAutodetect()
ํจ์๋ฅผ ํตํด MPU-6050, HMC6553L๊ณผ ํต์ ์ ์๋ํด ์ฐ๊ฒฐ์ฌ๋ถ๋ฅผ ํ์ธํ๊ณ , ๊ธฐ๋ณธ ์ค์ ๊ฐ์ผ๋ก ์ผ์๋ฅผ ์ด๊ธฐํ ํ๋ค.
imuInit()
ํจ์์์ ์ง์๊ธฐ์ผ์์ ํ์ํ ๋ณ์๋ค์ ์ด๊ธฐํ ํ๋ค.
๋ง์ง๋ง์ผ๋ก ๋๋ฒ๊น
์ ์ํด serialInit(115200)
ํจ์๋ก PA10,9(Rx,Tx) ํฌํธ๋ก ์๋ฆฌ์ผํต์ ์ ํ ์ ์๊ฒ, ํฌํธ๋ฅผ ์ฐ๋ค.
Sensor ๊ตฌ์กฐ์ฒด
๊ฐ์๋ ์ผ์, ์์ด๋ก์ค์ฝํ, ์ง์๊ธฐ ์ผ์๋ sensor_t ๊ตฌ์กฐ์ฒด๋ก ํํ๋๋ค. ๋ฉค๋ฒํจ์ํฌ์ธํฐ init, read๋ฅผ ํตํด ์ผ์๋ฅผ ์ด๊ธฐํํ๊ณ , ์ ๋ณด๋ฅผ ์ฝ์ด์จ๋ค. ๋ค์ํ ์ผ์์ ๋ง์ถฐ ํ์ฅ์ํฌ ์ ์๋๋ก ๋์์ธ ๋์๋ค. C++์ ์ถ์ ํด๋์ค์ ๋ฎ์๋ค.
typedef struct sensor_t {
sensorInitFuncPtr init; // initialize function
sensorReadFuncPtr read; // read 3 axis data function
sensorReadFuncPtr temperature; // read temperature if available
float scale; // scalefactor (currently used for gyro only, todo for accel)
} sensor_t;
typedef void (*sensorInitFuncPtr)(sensor_align_e align); // sensor init prototype
typedef void (*sensorReadFuncPtr)(int16_t *data); // sensor read and align prototype
typedef enum {
ALIGN_DEFAULT = 0, // driver-provided alignment
CW0_DEG = 1,
CW90_DEG = 2,
CW180_DEG = 3,
CW270_DEG = 4,
CW0_DEG_FLIP = 5,
CW90_DEG_FLIP = 6,
CW180_DEG_FLIP = 7,
CW270_DEG_FLIP = 8
} sensor_align_e;
sensorsAutodetect() ํจ์
MPU-6050 ๊ณผ HMC5883L ์ผ์๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํ์ง ๊ฒ์ฌํ๋ค.
mpu6050Detect()
ํจ์์ ๊ดํด์๋ Baseflight MPU-6050๋ฌธ์๋ฅผ ์ฐธ์กฐํ์.
hmc5883lDetect()
ํจ์์ ๊ดํด์๋ Baseflight HMC5883L๋ฌธ์๋ฅผ ์ฐธ์กฐํ์.
sensor_t acc; // acc access functions
sensor_t gyro; // gyro access functions
sensor_t mag; // mag access functions
uint8_t accHardware = ACC_DEFAULT; // which accel chip is used/detected
uint8_t magHardware = MAG_DEFAULT;
bool sensorsAutodetect(void)
{
int16_t deg, min;
// Autodetect gyro hardware. We have MPU3050 or MPU6050 or MPU6500 on SPI
if (mpu6050Detect(&acc, &gyro, mcfg.gyro_lpf, &core.mpu6050_scale))
{
}
else
{
// if this fails, we get a beep + blink pattern. we're doomed, no gyro or i2c error.
return false;
}
mpu6050Detect(&acc, &gyro, mcfg.gyro_lpf, &core.mpu6050_scale); // yes, i'm rerunning it again. re-fill acc struct
accHardware = ACC_MPU6050;
// Now time to init things, acc first
acc.init(mcfg.acc_align);
// this is safe because either mpu6050 or mpu3050 or lg3d20 sets it, and in case of fail, we never get here.
gyro.init(mcfg.gyro_align);
if (hmc5883lDetect(&mag))
{
magHardware = MAG_HMC5883L;
}
// calculate magnetic declination
deg = cfg.mag_declination / 100;
min = cfg.mag_declination % 100;
magneticDeclination = (deg + ((float)min * (1.0f / 60.0f))) * 10; // heading is in 0.1deg units
return true;
}
์ผ์ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
- BaseFlight Sensor2 ๋ฌธ์์ ์ค๋ช ๋์ด ์๋ค.
IMU ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ ์ผ์ ๊ฐ ๊ณ์ฐ
- Baseflight IMU ๋ฌธ์์ ์ค๋ช ๋์ด์๋ค.