这几天看pixhawk代码中关于传感器的代码,下面是一些记录。先说下,大家看pixhawk的代码可能不知道从哪开始,我个人是从启动应用的脚本看起的:rcS。这个脚本是操作系统启动以后,具体启动应用的先后顺序,按照这个顺序研究或者修改代码也可以让你理解运行pixhawk代码的飞控的工作流程,比较符合认识事物的过程。rcS会按照一定顺序调用其它脚本,如下面关于传感器的部分,rcS调用rc.sensors脚本。另外,脚本里启动某个程序,如mpu6000 start,在代码中要对应关系也比较容易,每个应用程序或者驱动启动都是start启动的,对应的mpu6000的代码的命令行参数会解析“start”,然后启动具体的操作。如果你用source insight看代码,那么找到mpu6000.cpp,然后搜索start,就可以定位程序的开始了。不至于太无目的。还有一点,根据rcS找到对应的代码,还可以让你很快找到哪些源文件没有用到,这样就可以快速定位到你要修改的文件啦。下面正文:下面内容是传感器有关的信息,供大家参考,可能有理解不正确的地方,大家发现哪里有不合理的地方,可以补充。互相共勉。看sensors.cpp这个文件。从task_main看起。大体结构是:Init(accel,gyro,mag,baro,adc)?setupfds?while(poll?pulish)很简洁。这种编程风格值得推荐。函数最好都写成这样。唯一感觉不太理想的地方就是函数太长。这点是不是很重要?在init阶段,一共初始化的传感器有:accel,gyro,mag,baro,adc其中accel和gyro是使用高精度定时器来保证周期的准确度。Accel:默认使用的是mpu6000。通过ioctl设置采样速度,这个接口实际操作的是底层的实际硬件,如果系统连接mpu6000,那就是操作mpu6000,如果没有连接mpu6000,那就是操作LSM303D。如果使用的是mpu6000,则设置采样周期800us。获得数据后有一个二阶低通滤波,然后publish给sensors.如果没有mpu6000,那就设置LSM303D,设置采样周期是1050us,然后也是通过一个二阶低通滤波,然后publish给sensors。Mpu6000的accel范围是-8g---+8g.Gyro范围是2000度,弧度数自己算。Gyro: 默认使用的是mpu6000.也是通过ioctl设置,如果系统连接mpu6000,那就是操作mpu6000,如果没有连接mpu6000,那就是操作L3GD20.如果使用的是mpu6000,则和使用mpu6000accel的设置一样,周期也是800us。如果使用的是L3GD20(L3G4200D),采集周期是716us,如果是L3G4200D,则周期是650us。以上的不管是使用mpu6000,还是L3GD20还是L3G4200D,采集的数据都通过低通滤波,然后publish到sensors.MAG:默认使用的是hmc5883LSM303D,mag采集频率是100Hz,没有滤波。直接publish。LSM303D的采集频率较低,但是还是放在了高精度定时器的操作里,有点不太明白,既然频率要求不要,为何要放在定时器的控制下呢?窃以为可能是下面原因:ALSM303D同时也是accel传感器,为了统一合适和使用BLSM303D是第二选择,第一选择是HMC5883.2Hmc5883,采集频率是150Hz,也没有滤波,但是xyz轴有相互转换的过程,然后publish。 其中scale的范围如下:#defineFLT_EPSILON 1.1920929e-07F(-FLT_EPSILON+ 1.0f每次从硬件读取的数据有效范围(xyz相同):(abs(report.x)Hmc5883的操作分成两部分,首先发送采集命令,然后延时,接下来读取数据。循环操作不是放在定时器里的,而是在每次读到数据以后,再次发送采集命令,然后安装回调函数,在延时一定时间后再次执行,这里用的是系统提供的任务队列,高优先级任务队列。work_queue(HPWORK, &_work, (worker_t)&HMC5883::cycle_trampoline, this, USEC2TICK(HMC5883_CONVERSION_INTERVAL));BARO:默认使用的是ms5611气压采集周期是100Hz,详细而言应该是温度25Hz,气压75Hz,即每采集一次温度值,计算用于温度补偿的三个值:_TEMP、_OFF、_SENS。然后采集三次气压值。根据上面的三个值进行计算,求出气压值,在根据气压值计算出海拔高度,然后把气压,高度值publish到sensors。气压具体的采集周期是这样的(假设当前时间是10ms):10ms(采集温度)?20ms(采集气压,publish)?30ms(采集气压,pulish)?40ms(采集气压,publish)?50ms(采集温度)。。。。。。。可见,采集温度的周期实际是40ms,而气压采集是每40ms三次。 另外,ms5611的调用方式也不是使用定时器,和hmc5883相同,使用高优先级任务队列:work_queue(HPWORK, &_work, (worker_t)&MS5611::cycle_trampoline, this, USEC2TICK(MS5611_CONVERSION_INTERVAL));