PX4模块设计之三十六:MulticopterPositionControl模块

2023-05-16

PX4模块设计之三十六:MulticopterPositionControl模块

  • 1. MulticopterPositionControl模块简介
  • 2. 模块入口函数
    • 2.1 主入口mc_pos_control_main
    • 2.2 自定义子命令custom_command
  • 3. MulticopterPositionControl模块重要函数
    • 3.1 task_spawn
    • 3.2 instantiate
    • 3.3 init
    • 3.4 Run
  • 4. 总结
  • 5. 参考资料

1. MulticopterPositionControl模块简介

### Description
The controller has two loops: a P loop for position error and a PID loop for velocity error.
Output of the velocity controller is thrust vector that is split to thrust direction
(i.e. rotation matrix for multicopter orientation) and thrust scalar (i.e. multicopter thrust itself).

The controller doesn't use Euler angles for its work, they are generated only for more human-friendly control and
logging.

mc_pos_control <command> [arguments...]
 Commands:
   start
     [vtol]      VTOL mode

   stop

   status        print status info

注:print_usage函数是具体对应实现。

class MulticopterPositionControl : public ModuleBase<MulticopterPositionControl>, public control::SuperBlock,
	public ModuleParams, public px4::ScheduledWorkItem

注:MulticopterPositionControl模块采用了ModuleBase和WorkQueue设计。

2. 模块入口函数

2.1 主入口mc_pos_control_main

同样继承了ModuleBase,由ModuleBase的main来完成模块入口。

mc_pos_control_main
 └──> return MulticopterPositionControl::main(argc, argv)

2.2 自定义子命令custom_command

模块仅支持start/stop/status命令,不支持其他自定义命令。

MulticopterPositionControl::custom_command
 └──> return print_usage("unknown command");

3. MulticopterPositionControl模块重要函数

3.1 task_spawn

这里主要初始化了MulticopterPositionControl对象,后续通过WorkQueue来完成进行轮询。

MulticopterPositionControl::task_spawn
 ├──> vtol = false
 ├──> <argc > 1><strcmp(argv[1], "vtol") == 0>
 │   └──> vtol = true
 ├──> MulticopterPositionControl *instance = new MulticopterPositionControl(vtol)
 ├──> <instance>
 │   ├──> _object.store(instance)
 │   ├──> _task_id = task_id_is_work_queue
 │   └──> <instance->init()>
 │       └──> return PX4_OK
 ├──> <else>
 │   └──> PX4_ERR("alloc failed")
 ├──> delete instance
 ├──> _object.store(nullptr)
 └──> _task_id = -1

3.2 instantiate

注:鉴于该模块不采用任务(线程),所以ModuleBase::run_trampoline无需执行,所以可以不实现。

3.3 init

在task_spawn中使用,对_local_pos_sub成员变量进行事件回调注册(当有vehicle_local_position消息时,会调用SubscriptionCallbackWorkItem::ScheduleNow,再触发RCUpdate::Run过程),同时在MulticopterPositionControl::init过程,触发第一次ScheduleNow。

MulticopterPositionControl::init
 ├──> <!_local_pos_sub.registerCallback()>
 │   ├──> PX4_ERR("callback registration failed")
 │   └──> return false
 ├──> _time_stamp_last_loop = hrt_absolute_time()
 ├──> ScheduleNow()
 └──> return true

3.4 Run

在Run过程中调用ScheduleDelayed(100_ms)规划下一次定时轮询。

MulticopterPositionControl::Run
 ├──> [优雅退出处理]
 ├──> ScheduleDelayed(100_ms)  // reschedule backup
 ├──> parameters_update(false)
 ├──> <!_local_pos_sub.update(&vehicle_local_position)>
 │   └──> return
 ├──> const float dt = math::constrain(((vehicle_local_position.timestamp_sample - _time_stamp_last_loop) * 1e-6f), 0.002f, 0.04f)
 ├──> _time_stamp_last_loop = vehicle_local_position.timestamp_sample
 ├──> setDt(dt) // set _dt in controllib Block for BlockDerivative
 ├──> <_vehicle_control_mode_sub.updated()>
 │   ├──> const bool previous_position_control_enabled = _vehicle_control_mode.flag_multicopter_position_control_enabled
 │   └──> <_vehicle_control_mode_sub.update(&_vehicle_control_mode)>
 │       ├──> <!previous_position_control_enabled && _vehicle_control_mode.flag_multicopter_position_control_enabled>
 │       │   └──> _time_position_control_enabled = _vehicle_control_mode.timestamp
 │       └──> <else if (previous_position_control_enabled && !_vehicle_control_mode.flag_multicopter_position_control_enabled>
 │           └──> reset_setpoint_to_nan(_setpoint)  // clear existing setpoint when controller is no longer active
 ├──> _vehicle_land_detected_sub.update(&_vehicle_land_detected)
 ├──> <_param_mpc_use_hte.get()><_hover_thrust_estimate_sub.update(&hte)><hte.valid>
 │   └──> _control.updateHoverThrust(hte.hover_thrust)
 ├──> _trajectory_setpoint_sub.update(&_setpoint)
 ├──> <(_setpoint.timestamp != 0) && (_setpoint.timestamp < vehicle_local_position.timestamp)> // adjust existing (or older) setpoint with any EKF reset deltas
 │   ├──> <vehicle_local_position.vxy_reset_counter != _vxy_reset_counter>
 │   │   ├──> _setpoint.vx += vehicle_local_position.delta_vxy[0]
 │   │   └──> _setpoint.vy += vehicle_local_position.delta_vxy[1]
 │   ├──> <vehicle_local_position.vz_reset_counter != _vz_reset_counter>
 │   │   └──> _setpoint.vz += vehicle_local_position.delta_vz
 │   ├──> <vehicle_local_position.xy_reset_counter != _xy_reset_counter>
 │   │   ├──> _setpoint.x += vehicle_local_position.delta_xy[0]
 │   │   └──> _setpoint.y += vehicle_local_position.delta_xy[1]
 │   ├──> <vehicle_local_position.z_reset_counter != _z_reset_counter>
 │   │   └──> _setpoint.z += vehicle_local_position.delta_z
 │   └──> <vehicle_local_position.heading_reset_counter != _heading_reset_counter>
 │       └──> _setpoint.yaw = wrap_pi(_setpoint.yaw + vehicle_local_position.delta_heading)
 ├──> <vehicle_local_position.vxy_reset_counter != _vxy_reset_counter>
 │   ├──> _vel_x_deriv.reset()
 │   └──> _vel_y_deriv.reset()
 ├──> vehicle_local_position.vz_reset_counter != _vz_reset_counter) {
 │   └──> _vel_z_deriv.reset()
 ├──> [save latest reset counters]
 │   ├──> _vxy_reset_counter = vehicle_local_position.vxy_reset_counter
 │   ├──> _vz_reset_counter = vehicle_local_position.vz_reset_counter
 │   ├──> _xy_reset_counter = vehicle_local_position.xy_reset_counter
 │   ├──> _z_reset_counter = vehicle_local_position.z_reset_counter
 │   └──> _heading_reset_counter = vehicle_local_position.heading_reset_counter
 ├──> PositionControlStates states{set_vehicle_states(vehicle_local_position)}
 ├──> <_vehicle_control_mode.flag_multicopter_position_control_enabled><(_setpoint.timestamp < _time_position_control_enabled) && (vehicle_local_position.timestamp_sample > _time_position_control_enabled)>
 │   └──> _setpoint = generateFailsafeSetpoint(vehicle_local_position.timestamp_sample, states) // set failsafe setpoint if there hasn't been a new, trajectory setpoint since position control started
 ├──> <_vehicle_control_mode.flag_multicopter_position_control_enabled && (_setpoint.timestamp >= _time_position_control_enabled)>
 │   └──> _vehicle_constraints_sub.update(&_vehicle_constraints) // update vehicle constraints and handle smooth takeoff
 ├──> <!PX4_ISFINITE(_vehicle_constraints.speed_up) || (_vehicle_constraints.speed_up > _param_mpc_z_vel_max_up.get())> // fix to prevent the takeoff ramp to ramp to a too high value or get stuck because of NAN
 │   └──> _vehicle_constraints.speed_up = _param_mpc_z_vel_max_up.get() // TODO: this should get obsolete once the takeoff limiting moves into the flight tasks
 ├──> <_vehicle_control_mode.flag_control_offboard_enabled>
 │   ├──> const bool want_takeoff = _vehicle_control_mode.flag_armed && (vehicle_local_position.timestamp_sample < _setpoint.timestamp + 1_s)
 │   ├──> <want_takeoff && PX4_ISFINITE(_setpoint.z) && (_setpoint.z < states.position(2))>
 │   │   └──> _vehicle_constraints.want_takeoff = true
 │   ├──> <want_takeoff && PX4_ISFINITE(_setpoint.vz) && (_setpoint.vz < 0.f)>
 │   │   └──> _vehicle_constraints.want_takeoff = true
 │   ├──> <want_takeoff && PX4_ISFINITE(_setpoint.acceleration[2]) && (_setpoint.acceleration[2] < 0.f)>
 │   │   └──> _vehicle_constraints.want_takeoff = true
 │   └──> <else>
 │       └──> _vehicle_constraints.want_takeoff = false
 ├──> [ override with defaults ]
 │   ├──> _vehicle_constraints.speed_up = _param_mpc_z_vel_max_up.get()
 │   └──> _vehicle_constraints.speed_down = _param_mpc_z_vel_max_dn.get()
 ├──> _takeoff.updateTakeoffState(_vehicle_control_mode.flag_armed, _vehicle_land_detected.landed, _vehicle_constraints.want_takeoff, _vehicle_constraints.speed_up, false, vehicle_local_position.timestamp_sample) // handle smooth takeoff
 ├──> const bool not_taken_off             = (_takeoff.getTakeoffState() < TakeoffState::rampup)
 ├──> const bool flying                    = (_takeoff.getTakeoffState() >= TakeoffState::flight)
 ├──> const bool flying_but_ground_contact = (flying && _vehicle_land_detected.ground_contact)
 ├──> <!flying>
 │   └──> _control.setHoverThrust(_param_mpc_thr_hover.get())
 ├──> <_takeoff.getTakeoffState() == TakeoffState::rampup>
 │   └──> _setpoint.acceleration[2] = NAN  // make sure takeoff ramp is not amended by acceleration feed-forward
 ├──> <not_taken_off || flying_but_ground_contact>
 │   ├──> reset_setpoint_to_nan(_setpoint) // we are not flying yet and need to avoid any corrections
 │   ├──> _setpoint.timestamp = vehicle_local_position.timestamp_sample
 │   ├──> Vector3f(0.f, 0.f, 100.f).copyTo(_setpoint.acceleration) // High downwards acceleration to make sure there's no thrust
 │   └──> _control.resetIntegral() // prevent any integrator windup
 ├──> [limit tilt during takeoff ramupup]
 │   ├──> const float tilt_limit_deg = (_takeoff.getTakeoffState() < TakeoffState::flight) ? _param_mpc_tiltmax_lnd.get() : _param_mpc_tiltmax_air.get()
 │   ├──> _control.setTiltLimit(_tilt_limit_slew_rate.update(math::radians(tilt_limit_deg), dt))
 │   ├──> const float speed_up = _takeoff.updateRamp(dt, PX4_ISFINITE(_vehicle_constraints.speed_up) ? _vehicle_constraints.speed_up : _param_mpc_z_vel_max_up.get())
 │   └──> const float speed_down = PX4_ISFINITE(_vehicle_constraints.speed_down) ? _vehicle_constraints.speed_down :_param_mpc_z_vel_max_dn.get()
 ├──> const float minimum_thrust = flying ? _param_mpc_thr_min.get() : 0.f  // Allow ramping from zero thrust on takeoff
 ├──> _control.setThrustLimits(minimum_thrust, _param_mpc_thr_max.get())
 ├──> float max_speed_xy = _param_mpc_xy_vel_max.get()
 ├──> <PX4_ISFINITE(vehicle_local_position.vxy_max)>
 │   └──> max_speed_xy = math::min(max_speed_xy, vehicle_local_position.vxy_max)
 ├──> _control.setVelocityLimits(max_speed_xy, math::min(speed_up, _param_mpc_z_vel_max_up.get()), math::max(speed_down, 0.f))// takeoff ramp starts with negative velocity limit
 ├──> _control.setInputSetpoint(_setpoint)
 ├──> <!PX4_ISFINITE(_setpoint.z) && PX4_ISFINITE(_setpoint.vz) && (fabsf(_setpoint.vz) > FLT_EPSILON) && PX4_ISFINITE(vehicle_local_position.z_deriv) && vehicle_local_position.z_valid && vehicle_local_position.v_z_valid>// update states
 │	 │    // A change in velocity is demanded and the altitude is not controlled.
 │	 │    // Set velocity to the derivative of position
 │	 │    // because it has less bias but blend it in across the landing speed range
 │	 │    //  <  MPC_LAND_SPEED: ramp up using altitude derivative without a step
 │	 │    //  >= MPC_LAND_SPEED: use altitude derivative
 │   ├──> float weighting = fminf(fabsf(_setpoint.vz) / _param_mpc_land_speed.get(), 1.f)
 │   └──> states.velocity(2) = vehicle_local_position.z_deriv * weighting + vehicle_local_position.vz * (1.f - weighting)
 ├──> _control.setState(states)
 ├──> <!_control.update(dt)>  // Run position control, Failsafe
 │   ├──> _vehicle_constraints = {0, NAN, NAN, false, {}} // reset constraints
 │   ├──> _control.setInputSetpoint(generateFailsafeSetpoint(vehicle_local_position.timestamp_sample, states))
 │   ├──> _control.setVelocityLimits(_param_mpc_xy_vel_max.get(), _param_mpc_z_vel_max_up.get(), _param_mpc_z_vel_max_dn.get())
 │   └──> _control.update(dt)
 ├──> [Publish internal position control setpoints] 
 │   ├──> _vehicle_local_position_setpoint_s local_pos_sp{}
 │   ├──> __control.getLocalPositionSetpoint(local_pos_sp)
 │   ├──> _local_pos_sp.timestamp = hrt_absolute_time()
 │   ├──> __local_pos_sp_pub.publish(local_pos_sp)  // on top of the input/feed-forward setpoints these containt the PID corrections, This message is used by other modules (such as Landdetector) to determine vehicle intention.
 │   ├──> _vehicle_attitude_setpoint_s attitude_setpoint{}
 │   ├──> __control.getAttitudeSetpoint(attitude_setpoint)
 │   ├──> _attitude_setpoint.timestamp = hrt_absolute_time()
 │   └──> __vehicle_attitude_setpoint_pub.publish(attitude_setpoint) // Publish attitude setpoint output
 ├──> <else>// an update is necessary here because otherwise the takeoff state doesn't get skipped with non-altitude-controlled modes
 │   └──> _takeoff.updateTakeoffState(_vehicle_control_mode.flag_armed, _vehicle_land_detected.landed, false, 10.f, true, vehicle_local_position.timestamp_sample)
 ├──> const uint8_t takeoff_state = static_cast<uint8_t>(_takeoff.getTakeoffState())
 └──> <takeoff_state != _takeoff_status_pub.get().takeoff_state || !isEqualF(_tilt_limit_slew_rate.getState(), _takeoff_status_pub.get().tilt_limit)>
     ├──> _takeoff_status_pub.get().takeoff_state = takeoff_state
     ├──> _takeoff_status_pub.get().tilt_limit = _tilt_limit_slew_rate.getState()
     ├──> _takeoff_status_pub.get().timestamp = hrt_absolute_time()
     └──> _takeoff_status_pub.update()  // Publish takeoff status

4. 总结

具体逻辑业务后续再做深入,从模块代码角度:

  • 输入
uORB::SubscriptionCallbackWorkItem _local_pos_sub{this, ORB_ID(vehicle_local_position)};	/**< vehicle local position */

uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};

uORB::Subscription _hover_thrust_estimate_sub{ORB_ID(hover_thrust_estimate)};
uORB::Subscription _trajectory_setpoint_sub{ORB_ID(trajectory_setpoint)};
uORB::Subscription _vehicle_constraints_sub{ORB_ID(vehicle_constraints)};
uORB::Subscription _vehicle_control_mode_sub{ORB_ID(vehicle_control_mode)};
uORB::Subscription _vehicle_land_detected_sub{ORB_ID(vehicle_land_detected)};
  • 输出
uORB::PublicationData<takeoff_status_s>              _takeoff_status_pub{ORB_ID(takeoff_status)};
uORB::Publication<vehicle_attitude_setpoint_s>	     _vehicle_attitude_setpoint_pub{ORB_ID(vehicle_attitude_setpoint)};
uORB::Publication<vehicle_local_position_setpoint_s> _local_pos_sp_pub{ORB_ID(vehicle_local_position_setpoint)};	/**< vehicle local position setpoint publication */

5. 参考资料

【1】PX4开源软件框架简明简介
【2】PX4模块设计之十一:Built-In框架
【3】PX4模块设计之十二:High Resolution Timer设计
【4】PX4模块设计之十三:WorkQueue设计
【5】PX4模块设计之十七:ModuleBase模块
【6】PX4模块设计之三十:Hysteresis类
【7】PX4 modules_main

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PX4模块设计之三十六:MulticopterPositionControl模块 的相关文章

  • pixhawk: px4代码初学分析:追溯电机控制--pwm输出

    追溯电机控制 pwm输出 正常工作状态下pwm输出过程简述 xff1a 其他状态下pwm输出 xff1a 正常工作状态下pwm输出过程简述 xff1a 姿态解算部分得出姿态控制量通过px4io cpp把姿态控制量发送给IOIO串口读取姿态控
  • 编译PX4固件

    PX4编译 文章目录 PX4编译疑难杂症bug1bug2catkin build isolated 官方脚本Step1Step2 安装常用依赖Step3 创建并运行脚本Step4 补全代码子模块Step5 验证仿真 官方offboard 例
  • Ubuntu20.04+MAVROS+PX4+Gazebo保姆级安装教程

    Ubuntu20 04 43 MAVROS 43 PX4 43 Gazebo 安装PX4步骤安装MAVROS安装QGCPX4仿真 安装PX4步骤 从github上clone源码 span class token function git s
  • PX4无人机 - 键盘控制飞行代码

    PX4无人机 键盘控制飞行代码 仿真效果 实机效果 由于图片限制5M以内 xff0c 只能上传一小段了 xff0c 整段视频请点击链接 Pixhawk 6c 无人机 键盘控制无人机 Offboard模式 核心 xff1a 发布 mavros
  • px4源码编译指南

    px4源码编译指南 强烈推荐大家去看官网的英文文档 xff0c 国内的博客杂七杂八 xff0c 官网的中文也很久没有更新 xff0c 这几天自己踩了很多坑 xff0c 写个教程希望能帮助到大家 xff08 本文选用平台是pixhawk1 1
  • px4 avoidance笔记

    最近在用px4官方的avoidance代码跑硬件避障 xff0c 官方介绍了只要生成符合sensor msgs PointCloud2点云信息就能使用 xff0c 因此为了应用长基线双目 xff0c 没有使用realsense的相机 xff
  • 初学PX4之环境搭建

    文章转自 xff1a http www jianshu com p 36dac548106b 前言 前段时间linux崩溃了 xff0c 桌面进去后只有背景 xff0c 折腾好久没搞定 xff0c 为了节省时间索性重装了系统 xff0c 同
  • PX4进入系统控制台以及运行程序

    这里提供进入控制台两种办法 1 运行 Tools mavlink shell py dev ttyACM0 是我进入Px4系统控制台的命令 xff0c 进入之后应该是这样 Pixhawk src Firmware Tools mavlink
  • PX4模块设计之二十六:BatteryStatus模块

    PX4模块设计之二十六 xff1a BatteryStatus模块 1 BatteryStatus模块简介2 模块入口函数2 1 主入口battery status main2 2 自定义子命令custom command 3 Batter
  • PX4模块设计之三十一:ManualControl模块

    PX4模块设计之三十一 xff1a ManualControl模块 1 ManualControl模块简介2 模块入口函数2 1 主入口manual control main2 2 自定义子命令custom command 3 Manual
  • PX4模块设计之四十六:dataman模块

    PX4模块设计之四十六 xff1a dataman模块 1 dataman模块简介2 模块入口函数dataman main3 dataman模块重要函数3 1 start3 2 stop3 3 status3 4 task main 4 A
  • mavros连接px4失败的usb-ttl原因

    问题描述 xff1a 最近在搞mavros xff0c 以方便协处理器和pixhawk通讯 xff0c 在按照官网教程安装mavros xff0c 设置px4 xff0c 连接硬件之后发现mavros卡在中间下不去 xff1a MAVROS
  • px4仿真无法起飞问题(Failsafe enabled: no datalink)

    报错信息 问题描述 xff1a 使用JMAVSim和gazebo仿真px4起飞时报错如下 xff1a WARN commander Failsafe enabled no datalink 说不安全 解决方法 打开QGC 就可以起飞了
  • 【px4】运行mavsdk中的offboard example

    运行MAVSDK中的offboard例子时无人机不执行 想控制无人机前后左右移动 xff0c 在按照官方教程实现offboard 插件的时候 发现用action插件能正常起飞和降落 但是一旦执行到offboard的插件代码的时候就会自动降落
  • PX4飞控之自主返航(RTL)控制逻辑

    本文基于PX4飞控1 5 5版本 xff0c 分析导航模块中自护返航模式的控制逻辑和算法 自主返航模式和导航中的其他模式一样 xff0c 在Navigator main函数中一旦触发case vehicle status s NAVIGAT
  • PX4软件在环仿真注意点

    注 xff1a 最新内容参考PX4 user guide 点击此处 PX4下载指定版本代码和刷固件的三种方式 点击此处 PX4sitl固件编译方法 点击此处 PX4开发指南 点击此处 PX4无人机仿真 Gazebo 点击此处 px4仿真 知
  • PX4模块设计之二十七:LandDetector模块

    PX4模块设计之二十七 xff1a LandDetector模块 1 LandDetector模块简介2 模块入口函数2 1 主入口land detector main2 2 自定义子命令custom command 3 LandDetec
  • 【PX4 飞控剖析】06 树莓派加载安装ROS,Mavros以及PX4固件

    PX4 飞控剖析 06 树莓派加载安装Mavros以及PX4固件 1 树莓派 刷镜像1 1 用Win32DiskImager刷入ubuntu mate 16 04 2 desktop armhf raspberry pi的镜像 1 2 开机
  • PX4通过参数脚本给飞控导入参数

    PX4通过参数脚本给飞控导入参数 先找一架正常能飞的无人机连接地面站 在参数页面右上角点击工具 gt 保存到文件 保存的时候文件名注明参数的相关信息 然后将需要加载参数的无人机连接至地面站 xff0c 注意需要加载参数的无人机必须和保存的参
  • 四、无人机知识笔记(初级:基本运动原理)

    笔记来源于 沈阳无距科技 工业级无人机的中国名片 编程外星人 目录 一 多旋翼直升机 二 基本飞行姿态 三 多旋翼飞行原理 四 反扭力与偏航运动 五 螺旋桨 六 有刷电机和无刷电机 七 电调与PWM信号 八 动力电池 九 遥控器 十 机架设

随机推荐

  • PX4模块设计之二十一:uORB消息管理模块

    PX4模块设计之二十一 xff1a uORB消息管理模块 1 uORB模块构建模式2 uORB消息管理函数2 1 状态查询2 2 资源利用2 3 模块启动2 4 模块停止3 uORB消息接口3 1 消息主题注册3 2 消息主题去注册3 3
  • PX4模块设计之二十二:FlightModeManager模块

    PX4模块设计之二十二 xff1a FlightModeManager模块 1 FlightModeManager简介2 FlightModeManager启动3 FlightModeManager模块重要实现3 1 custom comm
  • PX4模块设计之二十三:自定义FlightTask

    PX4模块设计之二十三 xff1a 自定义FlightTask Step1 创建飞行模式文件夹Step2 创建飞行模式源代码和CMakeLists txt文件Step3 更新CMakeLists txt文件Step4 更新FlightTas
  • PX4模块设计之二十四:内部ADC模块

    PX4模块设计之二十四 xff1a 内部ADC模块 1 内部ADC模块简介2 模块入口函数2 1 主入口board adc main2 2 自定义子命令custom command 3 内部ADC模块重要函数3 1 task spawn3
  • PX4模块设计之二十五:DShot模块

    PX4模块设计之二十五 xff1a DShot模块 1 DShot模块简介2 DShot类继承关系3 模块入口函数3 1 主入口dshot main3 2 自定义子命令custom command 4 DShot模块重要函数4 1 task
  • PX4模块设计之二十六:BatteryStatus模块

    PX4模块设计之二十六 xff1a BatteryStatus模块 1 BatteryStatus模块简介2 模块入口函数2 1 主入口battery status main2 2 自定义子命令custom command 3 Batter
  • PX4模块设计之二十七:LandDetector模块

    PX4模块设计之二十七 xff1a LandDetector模块 1 LandDetector模块简介2 模块入口函数2 1 主入口land detector main2 2 自定义子命令custom command 3 LandDetec
  • CentOS-7 中安装VS Code 并启动

    VSCode安装 安装平台 xff1a CentOS7 安装方法 xff1a 1 在官网上下载64位 xff08 或者32位 xff09 的rpm包 xff08 官网地址 xff1a https code visualstudio com
  • PX4模块设计之二十八:RCInput模块

    PX4模块设计之二十八 xff1a RCInput模块 1 RCInput模块简介2 模块入口函数2 1 主入口rc input main2 2 自定义子命令custom command2 3 模块状态print status 重载 3 R
  • PX4模块设计之二十九:RCUpdate模块

    PX4模块设计之二十九 xff1a RCUpdate模块 1 RCUpdate模块简介2 模块入口函数2 1 主入口rc update main2 2 自定义子命令custom command2 3 模块状态print status 重载
  • PX4模块设计之三十:Hysteresis类

    PX4模块设计之三十 xff1a Hysteresis类 1 Hysteresis类简介2 Hysteresis类成员变量介绍3 Hysteresis类迟滞逻辑4 Hysteresis类重要方法4 1 Hysteresis bool ini
  • PX4模块设计之三十一:ManualControl模块

    PX4模块设计之三十一 xff1a ManualControl模块 1 ManualControl模块简介2 模块入口函数2 1 主入口manual control main2 2 自定义子命令custom command 3 Manual
  • PX4模块设计之三十二:AttitudeEstimatorQ模块

    PX4模块设计之三十二 xff1a AttitudeEstimatorQ模块 1 AttitudeEstimatorQ模块简介2 模块入口函数2 1 主入口attitude estimator q main2 2 自定义子命令custom
  • PX4模块设计之三十三:Sensors模块

    PX4模块设计之三十三 xff1a Sensors模块 1 Sensors模块简介2 模块入口函数2 1 主入口sensors main2 2 自定义子命令custom command2 3 模块状态print status 重载 3 Se
  • 树莓派(Raspberry Pi)miniDLNA服务搭建

    树莓派 Raspberry Pi miniDLNA服务搭建 1 MiniDLNA简介2 安装前提3 安装步骤4 服务配置5 进程配置6 参考资料7 补充资料7 1 配置外置硬盘 xff08 媒体库 xff09 7 2 配置samba符号链接
  • PX4模块设计之三十四:ControlAllocator模块

    PX4模块设计之三十四 xff1a ControlAllocator模块 1 ControlAllocator模块简介2 模块入口函数2 1 主入口control allocator main2 2 自定义子命令custom command
  • PX4模块设计之三十五:MulticopterAttitudeControl模块

    PX4模块设计之三十五 xff1a MulticopterAttitudeControl模块 1 MulticopterAttitudeControl模块简介2 模块入口函数2 1 主入口mc att control main2 2 自定义
  • 穿越机用途和机架尺寸

    穿越机用途和机架尺寸 1 穿越机的用途2 穿越机的机架3 机架的类型3 1 正X型机架3 2 宽X型机架3 3 长X型机架3 4 Hybrid机架3 5 涵道机架 4 总结 1 穿越机的用途 穿越机按功能分 xff0c 主要分为竞速Race
  • HC05和电脑蓝牙通讯

    通常情况下都是将HC05和HC04进行主从配对 xff0c 然后进行通讯 如果手边没有HC04其实可以使用笔记本自带的蓝牙和HC05进行通讯 配置方法如下 xff1a 将HC05配置为主机模式将电脑和HC05的保存连接删除 单击下方更多蓝牙
  • PX4模块设计之三十六:MulticopterPositionControl模块

    PX4模块设计之三十六 xff1a MulticopterPositionControl模块 1 MulticopterPositionControl模块简介2 模块入口函数2 1 主入口mc pos control main2 2 自定义