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
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传进来的值赋给哪个具体名字的变量(或对象)??
容我慢慢道来
针对具体编译的机型,所有被使用的参数登记在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来的!!!这不就串起来了嘛!!
其他配置参数的使用流程应该同理!!