ArduPilot提供了丰富的数据记录功能通过AP_Logger来管理数据记录1. AP_Logger::WriteBlock程序的数据记录主要通过AP_Logger::WriteBlock()函数来进行函数原型classAP_Logger{...voidWriteBlock(constvoid*pBuffer,uint16_tsize);...};表示写入一个大小为size的区块。这个区块为包含数据结构的区块常用的用法如下voidPlane::Log_Write_AETR(){structlog_AETRpkt{LOG_PACKET_HEADER_INIT(LOG_AETR_MSG),time_us:AP_HAL::micros64(),aileron:SRV_Channels::get_output_scaled(SRV_Channel::k_aileron),elevator:SRV_Channels::get_output_scaled(SRV_Channel::k_elevator),throttle:SRV_Channels::get_output_scaled(SRV_Channel::k_throttle),rudder:SRV_Channels::get_output_scaled(SRV_Channel::k_rudder),flap:SRV_Channels::get_slew_limited_output_scaled(SRV_Channel::k_flap_auto),steering:SRV_Channels::get_output_scaled(SRV_Channel::k_steering),speed_scaler:get_speed_scaler(),};logger.WriteBlock(pkt,sizeof(pkt));}如上为写入一个log_AETR数据结构的例子表示飞行器的控制信号结构体log_AETR的数据定义如下structPACKEDlog_AETR{LOG_PACKET_HEADER;//数据块的包头uint64_ttime_us;//时间微秒floataileron;//滚转控制floatelevator;//俯仰控制floatthrottle;//油门floatrudder;//偏航控制floatflap;//襟翼输出floatsteering;//转向控制floatspeed_scaler;//速度缩放因子};其中LOG_PACKET_HEADER为数据包头定义为两个字符的起头和一个msgid如下#defineLOG_PACKET_HEADERuint8_thead1,head2,msgid;对于不同类型的数据记录msgid不同对于log_AETR结构包头数据为LOG_PACKET_HEADER_INIT(LOG_AETR_MSG)其中#defineLOG_PACKET_HEADER_INIT(id)head1:HEAD_BYTE1,head2:HEAD_BYTE2,msgid:id表示两个起头字符HEAD_BYTE1和HEAD_BYTE2它们的定义如下#defineHEAD_BYTE10xA3// Decimal 163#defineHEAD_BYTE20x95// Decimal 149msgid为LOG_AETR_MSG定义在一个枚举类型enum中enumlog_messages{...LOG_AETR_MSG,...};这样就完成了一个数据块的写入数据块的含义由msgid确认每一个msgid对应了数据块的内容。2. LogStructure所有数据块的内容在Plane::log_structure[]中定义Plane::log_structure是一个数组记录了所有数据记录类型的含义通常定义如下conststructLogStructurePlane::log_structure[]{log_structure item1,log_structure item2,...{LOG_AETR_MSG,sizeof(log_AETR),AETR,Qfffffff,TimeUS,Ail,Elev,Thr,Rudd,Flap,Steer,SS,s-------,F-------,true},...}每一行为一个数据记录类型的定义分别对应不同类型的数据记录内容LOG_AETR_MSG也为其中的一行LogStructure的定义如下structLogStructure{uint8_tmsg_type;//数据记录类型uint8_tmsg_len;//数据记录长度constchar*name;//数据记录名称constchar*format;//数据记录格式constchar*labels;//数据项标签constchar*units;//数据项单位constchar*multipliers;//数据项比例因子boolstreaming;//是否可限制写入速度};对应LOG_AETR_MSG数据含义如下msg_type:LOG_AETR_MSG//数据记录idmsg_len:sizeof(log_AETR)//数据块大小name:AETR//数据类型名称format:Qfffffff//数据项类型Q表示uint64_t,f表示floatlabels:TimeUS,Ail,Elev,Thr,Rudd,Flap,Steer,SS//数据项标签units:s-------//数据项单位multipliers:F-------//数据项乘数因子streaming:true//是否可以限制写入速度允许WriteStreaming其中数据项格式类型定义如下格式字符数据类型说明bint8_t有符号8位整数Buint8_t无符号8位整数hint16_t有符号16位整数Huint16_t无符号16位整数iint32_t有符号32位整数Iuint32_t无符号32位整数qint64_t有符号64位整数Quint64_t无符号64位整数ffloat单精度浮点数ddouble双精度浮点数nchar[4]4字节字符数组通常用于存储短标识符Nchar[16]16字节字符数组Zchar[64]64字节字符数组Lint32_t专用于经纬度单位为1e-7度如-35.1332423°存储为-351332423Muint8_t无符号8位整数专用于存储飞行模式数据项单位定义如下单位字符对应的物理单位说明-无无单位如字符串或Pi等纯数值s秒时间戳 (TimeUS)、控制周期 (Dt)m米高度 (Alt)、距离、GPS位置精度d度deg姿态角 (Roll, Pitch)、角度误差%百分比油门输出 (Thr)、电机出力v伏特电池电压、传感器供电电压A安培电流、电池放电电流P帕斯卡气压计 (Press)、空速计 (DiffPress)O摄氏度温度 (Temp)、温控状态n米/秒空速、地速 (Airspeed, GSpd)k度/秒角速度 (Rate)、陀螺仪数据o米/秒² 加速度计数据 (AccX, AccY, AccZ)D纬度度GPS纬度 (Lat)U经度度GPS经度 (Lng)h航向度GPS航向、罗盘航向 (Heading)G高斯磁力计数据 (MagX, MagY, MagZ)S卫星数量GPS定位状态 (Sats)Y微秒PWM脉宽、RC输入值q转/分钟电机转速 (RPM)r弧度角度SI单位N牛顿推力、力Forcez赫兹控制频率Freq?未知未知物理单位乘数因子的字符定义如下字符乘数 (Multiplier)说明与典型用途-0无乘数用于字符串或无需缩放的数值?1乘数尚未确定时的占位符01e0缩放倍数为1即原始值即为标准单位值A1e-1乘以 0.1B1e-2乘以 0.01常用于将厘米转换为米除以100C1e-3乘以 0.001常用于将毫单位转换为标准单位F1e-6乘以 0.000001用于将微秒转换为秒3. 数据记录的查看ArduPilot的数据记录功能会在飞机飞行结束后产生.bin数据日志文件通常通过MissionPlanner地面站程序来查看数据日志文件如上在MissionPlanner窗口的左侧选项卡中选择DataFlash Logs然后选择Review a Log就可以选择对应的数据日志文件.bin打开出现数据日志窗口如下如图右侧包含所有的数据记录其中就包括AETR数据记录展开AETR会列出AETR包含的所有数据项勾选对应的数据项就会在左侧数据窗口显示数据曲线。其中横坐标为时间纵坐标为对应数据变量的数值。4. 新增数据记录在ArduPilot中新增一项数据记录可以按照如下1新增数据结构定义新增需要记录的数据结构定义比如新增一个debug类型的数据结构记录在LogStructure.h中增加如下数据结构定义structPACKEDlog_debug{LOG_PACKET_HEADER;uint64_ttime_us;floatdata1;floatdata2;floatdata3;floatdata4;floatdata5;floatdata6;};表示新增的数据记录结构其中包含时间微秒和6个数据记录项2新增数据结构描述新增对应的数据结构描述#defineLOG_STRUCTURE_DEBUG\{LOG_DEBUG_MSG,sizeof(log_debug),\DBG,Qffffff,TimeUS, Data1, Data2, Data3, Data4, Data5, Data6,s------,F------,true},其中LOG_DEBUG_MSG为数据记录的ID可以把它放到enum LogMessages中如下enumLogMessages:uint8_t{...LOG_DEBUG_MSG,..._LOG_LAST_MSG_};其中_LOG_LAST_MSG_表示最后一个消息项。数据结构描述可以放在LOG_COMMON_STRUCTURES的末尾表示为常用的数据记录结构如下#defineLOG_COMMON_STRUCTURES\...LOG_STRUCTURE_DEBUGLOG_COMMON_STRUCTURES是定义在Plane::log_structure列表中的如下conststructLogStructurePlane::log_structure[]{LOG_COMMON_STRUCTURES,...这样就可以进行数据记录了。3数据记录在进行上述数据记录定义后可在程序中进行数据记录的操作了大致如下floatdata1,data2,data3,data4,data5,data6;...//fill content of data1-data6log_debug pkt{LOG_PACKET_HEADER_INIT(LOG_DEBUG_MSG),time_us:AP_HAL::micros64(),data1:data1,data2:data2,data3:data3,data4:data4,data5:data5,data6:data6};AP::logger().WriteBlock(pkt,sizeof(log_debug));申明一个log_debug的数据变量pkg把需要记录数据内容填进去再调用AP_Logger::WriteBlock()函数就可以记录对应数据了。新增的数据记录可以在产生的飞行日志文件.bin中通过MissionPlanner等工具来查看。