ardupilot参数的从mavlink消息到底层参数赋值

专业名词释义,参数缩写

gimbal 云台,万向接头
failsafe 故障保护
Collective: 总距
Swashplate : 倾斜盘
SW: Swashplate 倾斜盘
RSC: Rotor Speed Control
RC: Radio Channel 无线通道
DDFP:Direct Drive Fixed Pitch 尾桨的类型,直驱、固定桨叶角
ESC:electronic speed controller 电子速度控制器
governor:调速器
throttle:油门
aileron stick 与roll有关的摇杆
elevator stick 与pitch有关的摇杆
collective 总距
blade pitch 桨距角
Thrust 推力,升力,拉力
RPM sensor 转速传感器
INS Inertial Sensor 惯性传感器
OSD 屏幕显示叠加
ADSB 航空防碰撞传感器
AFS advanced FaliSafe 高级故障检测处理

参数

ArduPilot有数百个参数,允许用户配置车辆飞行/驾驶的许多方面,包括姿态控制器增益等。
地面站或机载计算机如何利用mavlink实现修改飞控固件中的参数??

参数名的差异

地面站或Mavlink中的参数名:
https://ardupilot.org/copter/docs/parameters.html

在飞控代码中是通过参数的名字进行定位查找别设值的

ardupilot参数的从mavlink消息到底层参数赋值_第1张图片

进入正题

F12进线程 SCHED_TASK_CLASS(GCS, (GCS*)&copter._gcs, update_receive, 400, 180, 102),
update_receive ~> packetReceived ~> packetReceived ~> handleMessage ~> handle_common_message ~> handle_common_param_message ~> handle_param_set(以此为例)
不难发现
接收MavLink消息后会经过以下几个过程:

  • 解码 mavlink_msg_param_set_decode(&msg, &packet);
  • 根据参数名(msg_id)找到该参数 vp = AP_Param::find(key, &var_type, ¶meter_flags);
  • 赋值 vp->set_float(packet.param_value, var_type);

是如何完成赋值的?最终要将MavLink传进来的值赋给哪个具体名字的变量(或对象)??
容我慢慢道来
针对具体编译的机型,所有被使用的参数登记在Copter::var_info[]中;(以copter机型为例)
它的幅值在ArduCopter\Parameters.cpp中;

    struct Info {
        const char *name;
        const void *ptr;    // pointer to the variable in memory
        union {
            const struct GroupInfo *group_info;
            const struct GroupInfo **group_info_ptr; // when AP_PARAM_FLAG_INFO_POINTER is set in flags
            const float def_value;
            ptrdiff_t def_value_offset; // Default value offset from param object, when AP_PARAM_FLAG_DEFAULT_POINTER is set in flags
        };
        uint16_t flags;
        uint16_t key; // k_param_*
        uint8_t type; // AP_PARAM_*
    };

参数现在数组Copter::var_info[]中等级,然后为每个参数构造一个AP_Param类型:

    // constructor with var_info
    AP_Param(const struct Info *info)
    {
        _var_info = info;
        uint16_t i;
        for (i=0; info[i].type != AP_PARAM_NONE; i++) ;
        _num_vars = i;
#if AP_PARAM_DYNAMIC_ENABLED
        _num_vars_base = _num_vars;
#endif
        if (_singleton != nullptr) {
            AP_HAL::panic("AP_Param must be singleton");
        }
        _singleton = this;
    }

那具体的参数在底层是如何获取、赋值、和使用的呢??
PID使用的地方:

    // Compute the yaw angular velocity demand from the yaw angle error
    const float angleP_yaw = _p_angle_yaw.kP() * _angle_P_scale.z;

看看_p_angle_yaw.kP() 是啥:

    // angle controller P objects
    AC_P                _p_angle_roll;
    AC_P                _p_angle_pitch;
    AC_P                _p_angle_yaw;

再看看AC_P是个类:

/// @class	AC_P
/// @brief	Object managing one P controller
class AC_P {
public:
    /// Constructor for P that saves its settings to EEPROM
    ///
    /// @note	PIs must be named to avoid either multiple parameters with the
    ///			same name, or an overly complex constructor.
    ///
    /// @param  initial_p       Initial value for the P term.
    ///
    AC_P(const float &initial_p = 0.0f) :
        default_kp(initial_p)
    {
        AP_Param::setup_object_defaults(this, var_info);
    }

    CLASS_NO_COPY(AC_P);

    /// Iterate the P controller, return the new control value
    ///
    /// Positive error produces positive output.
    ///
    /// @param error	The measured error value
    /// @param dt		The time delta in milliseconds (note
    ///					that update interval cannot be more
    ///					than 65.535 seconds due to limited range
    ///					of the data type).
    ///
    /// @returns		The updated control output.
    ///
    float       get_p(float error) const;

    /// Load gain properties
    ///
    void        load_gains();

    /// Save gain properties
    ///
    void        save_gains();

    /// @name	parameter accessors
    //@{

    /// Overload the function call operator to permit relatively easy initialisation
    void operator() (const float p) { _kp.set(p); }

    // accessors
    AP_Float    &kP() { return _kp; }
    const AP_Float &kP() const { return _kp; }
    void        kP(const float v) { _kp.set(v); }

    static const struct AP_Param::GroupInfo        var_info[];

private:
    AP_Float        _kp;

    const float default_kp;
};

AC_P的构造函数:

    AC_P(const float &initial_p = 0.0f) :
        default_kp(initial_p)
    {
        AP_Param::setup_object_defaults(this, var_info);
    }

哦!!原来最终参数的值是从var_info来的!!!这不就串起来了嘛!!
其他配置参数的使用流程应该同理!!

你可能感兴趣的:(Ardupilot)