记录无人机的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);

    }

相关推荐
zh路西法9 小时前
【10天速通ROS2-PX4无人机】(一) 从零搭建仿真环境,妈妈再也不用担心我炸机了!
无人机·仿真·px4·ros2·gazebo
沈阳昊天环宇无人机小编辑1 天前
沈阳学无人机怎么选?沈阳昊天环宇:从合规取证到行业应用,构建低空经济时代的核心竞争力
无人机
JulyLi20192 天前
基于光电球机低空无人机智能追踪系统
无人机
小许同学记录成长2 天前
QGIS二次开发技术文档
图像处理·qt·信息可视化·无人机
GrepowTattu3 天前
新品发布|Tattu TA-BC无人机电池检测器上线,多通道充电状态尽在掌握
无人机
xuanshang_yutou4 天前
无人机调试起飞遇到的问题及注意事项
无人机
延凡科技4 天前
多场景落地复盘:端边云架构无人机智能巡检系统设计与实践
大数据·数据结构·人工智能·科技·架构·无人机·能源
科技大视界4 天前
无人机智能巡检服务商技术哪家强?
无人机
鼎艺创新科技5 天前
技术解析|基于三维GIS电子沙盘的无人机空地协同防控管理方案
无人机·三维电子沙盘·智能安防·无人机空地协同·全域可视化
沈阳昊天环宇无人机小编辑7 天前
沈阳无人机飞手如何破局?掌握激光点云三维建模,抢占低空测绘新赛道
无人机