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

1. 参数

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

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

在这里插入图片描述
其中 param_id 是 https://ardupilot.org/copter/docs/parameters.html 中的参数名,类型是 char.

3. 进入正题

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, &parameter_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来的!!!这不就串起来了嘛!!
其他配置参数的使用流程应该同理!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值