记录无人机的compass

可以从地面站看下用的哪些compass

校准代码

libraries/AP_Compass/AP_Compass_Calibration.cpp

////先累积多次样本

复制代码
void AP_Compass_Backend::accumulate_sample(Vector3f &field, uint32_t max_samples)
{
    // ... 旋转、修正 ...
    
    WITH_SEMAPHORE(_sem);
    
    Compass::mag_state &state = _compass._state[Compass::StateIndex(instance)];
    state.accum += field;          // 每次都累加
    state.accum_count++;
    
    if (max_samples && state.accum_count >= max_samples) {
        // 达到上限后,减半防止溢出
        state.accum_count /= 2;
        state.accum /= 2;
    }
}

//// drain_ 累积多次后排空

复制代码
void AP_Compass_Backend::drain_accumulated_samples(const Vector3f *scaling)
{
    WITH_SEMAPHORE(_sem);

    Compass::mag_state &state = _compass._state[Compass::StateIndex(instance)];

    if (state.accum_count == 0) {
        return;
    }

    if (scaling) {
        state.accum *= *scaling;
    }
    state.accum /= state.accum_count;

    publish_filtered_field(state.accum);

    state.accum.zero();
    state.accum_count = 0;
}

publish

复制代码
void AP_Compass_Backend::publish_filtered_field(const Vector3f &mag)
{
    // 1. 获取当前磁力计实例的状态
    Compass::mag_state &state = _compass._state[Compass::StateIndex(instance)];
    
    // 2. ★ 核心:保存最终数据 ★
    state.field = mag;  // 复制磁场向量到 state.field
    
    // 3. 更新时间戳(毫秒)
    state.last_update_ms = AP_HAL::millis();
    
    // 4. 更新时间戳(微秒)- 更高精度
    state.last_update_usec = AP_HAL::micros();
}

怎么获取field

复制代码
_compass.get_field

这里计算heading 需要把飞机扶正再计算

calculate_heading() 的工作流程:

  1. "看":从磁力计读取当前机体坐标系下的磁场向量

  2. "猜":从DCM提取横滚和俯仰(知道飞机歪了多少)

  3. "扶正":用横滚/俯仰把歪的磁场向量"扶正"到水平面

  4. "算":用水平面内的磁场方向算出航向角

  5. "修":加上磁偏角,得到地理航向

    /*
    calculate a compass heading given the attitude from DCM and the mag vector
    /
    float
    Compass::calculate_heading(const Matrix3f &dcm_matrix, uint8_t i) const
    {
    /

    This extracts a roll/pitch-only rotation which is then used to rotate the body frame field into earth frame so the heading can be calculated.
    One could do:
    float roll, pitch, yaw;
    dcm_matrix.to_euler(roll, pitch, yaw)
    Matrix3f rp_rot;
    rp_rot.from_euler(roll, pitch, 0)
    Vector3f ef = rp_rot * field

    复制代码
     Because only the X and Y components are needed it's more efficient to manually calculate:
    
         rp_rot = [ cos(pitch), sin(roll) * sin(pitch),  cos(roll) * sin(pitch)
                             0,              cos(roll),              -sin(roll)]
    
     If the whole matrix is multiplied by cos(pitch) the required trigonometric values can be extracted directly from the existing dcm matrix.
     This multiplication has no effect on the calculated heading as it changes the length of the North/East vector but not its angle.
    
         rp_rot = [ cos(pitch)^2, sin(roll) * sin(pitch) * cos(pitch),  cos(roll) * sin(pitch) * cos(pitch)
                               0,              cos(roll) * cos(pitch),              -sin(roll) * cos(pitch)]
    
     Preexisting values can be substituted in:
    
         dcm_matrix.c.x = -sin(pitch)
         dcm_matrix.c.y =  sin(roll) * cos(pitch)
         dcm_matrix.c.z =  cos(roll) * cos(pitch)
    
         rp_rot = [ cos(pitch)^2, dcm_matrix.c.y * -dcm_matrix.c.x,  dcm_matrix.c.z * -dcm_matrix.c.x
                               0,                   dcm_matrix.c.z,                   -dcm_matrix.c.y]
    
     cos(pitch)^2 is stil needed. This is the same as 1 - sin(pitch)^2.
     sin(pitch) is avalable as dcm_matrix.c.x

    */

    复制代码
     const float cos_pitch_sq = 1.0f-(dcm_matrix.c.x*dcm_matrix.c.x);
    
     // Tilt compensated magnetic field Y component:
     const Vector3f &field = get_field(i);
    
     const float headY = field.y * dcm_matrix.c.z - field.z * dcm_matrix.c.y;
    
     // Tilt compensated magnetic field X component:
     const float headX = field.x * cos_pitch_sq - dcm_matrix.c.x * (field.y * dcm_matrix.c.y + field.z * dcm_matrix.c.z);
    
     // magnetic heading
     // 6/4/11 - added constrain to keep bad values from ruining DCM Yaw - Jason S.
     const float heading = constrain_float(atan2f(-headY,headX), -M_PI, M_PI);
    
     // Declination correction
     return wrap_PI(heading + _declination);

    }

相关推荐
亥时无人机管理系统7 小时前
一网统飞低空管控平台源码 全域无人机集中管理系统功能与落地优势
私有化部署·无人机·低空经济·无人机管理系统·一网统飞·行业巡检
拓恒技术2 天前
从“可见光漏检”到“热异常锁定”:无人机河道排污口识别与溯源的技术链路
人工智能·视觉检测·无人机
QXWZ_IA2 天前
无人机自主巡检从半自动到全闭环的阶段划分与定位要求
人工智能·安全·无人机
AiNightVision2 天前
无人机夜视模块如何选择?——从参数指标到系统集成的完整选型指南
人工智能·算法·计算机视觉·车载系统·无人机·视频·智能硬件
qq_25294131683 天前
无人机视角公路两侧滑坡检测数据集 | 公路巡检 滑坡检测 地质灾害 无人机航拍9302期
yolo·目标检测·目标跟踪·无人机·地质灾害·无人机视角·滑坡检测
tianxuanjg3 天前
无人机科研轻量化结构件采购指南|高校实验室选型避坑:轻量化与结构强度如何兼顾
人工智能·经验分享·机器人·无人机·制造
大势智慧3 天前
大势智慧支撑武汉市第二十四届职业技能大赛无人机测绘操控员(三维数字化)赛项圆满举办
无人机·比赛·职业技能大赛·武汉·空间赋能·圆满举办
AC10074095 天前
【德信康】无人机射频功放多频段切换模块
无人机
我喜欢就喜欢5 天前
无人机正射色差:镶嵌线 shp + 羽化接缝实操思路
无人机·遥感
小O的算法实验室6 天前
IEEE IOTJ,基于点云网络辅助粒子群算法+三维无人机基站部署
无人机