第一步,POSCTL模式的进入

1、从遥控器模式开关进入。

首先在PX4IO的主循环中调用了io_publish_raw_rc(),从IO芯片获取遥控器的各通道输入,发布input_rc消息;

然后,在Sensors的主循环中调用rc_poll()函数,获取input_rc消息的内容,按照通道映射和校准信息将遥控器输入值重新计算并写入manual_control_setpoint消息中进行发布,发布内容包括;

         manual.y = get_rc_value(rc_channels_s::RC_CHANNELS_FUNCTION_ROLL, -1.0, 1.0);manual.x = get_rc_value(rc_channels_s::RC_CHANNELS_FUNCTION_PITCH, -1.0, 1.0);manual.r = get_rc_value(rc_channels_s::RC_CHANNELS_FUNCTION_YAW, -1.0, 1.0);manual.z = get_rc_value(rc_channels_s::RC_CHANNELS_FUNCTION_THROTTLE, 0.0, 1.0);manual.flaps = get_rc_value(rc_channels_s::RC_CHANNELS_FUNCTION_FLAPS, -1.0, 1.0);manual.aux1 = get_rc_value(rc_channels_s::RC_CHANNELS_FUNCTION_AUX_1, -1.0, 1.0);manual.aux2 = get_rc_value(rc_channels_s::RC_CHANNELS_FUNCTION_AUX_2, -1.0, 1.0);manual.aux3 = get_rc_value(rc_channels_s::RC_CHANNELS_FUNCTION_AUX_3, -1.0, 1.0);manual.aux4 = get_rc_value(rc_channels_s::RC_CHANNELS_FUNCTION_AUX_4, -1.0, 1.0);manual.aux5 = get_rc_value(rc_channels_s::RC_CHANNELS_FUNCTION_AUX_5, -1.0, 1.0);/* filter controls */manual.y = math::constrain(_filter_roll.apply(manual.y), -1.f, 1.f);manual.x = math::constrain(_filter_pitch.apply(manual.x), -1.f, 1.f);manual.r = math::constrain(_filter_yaw.apply(manual.r), -1.f, 1.f);manual.z = math::constrain(_filter_throttle.apply(manual.z), 0.f, 1.f);if (_parameters.rc_map_flightmode > 0) {/* the number of valid slots equals the index of the max marker minus one */const int num_slots = manual_control_setpoint_s::MODE_SLOT_MAX;/* the half width of the range of a slot is the total range* divided by the number of slots, again divided by two*/const float slot_width_half = 2.0f / num_slots / 2.0f;/* min is -1, max is +1, range is 2. We offset below min and max */const float slot_min = -1.0f - 0.05f;const float slot_max = 1.0f + 0.05f;/* the slot gets mapped by first normalizing into a 0..1 interval using min* and max. Then the right slot is obtained by multiplying with the number of* slots. And finally we add half a slot width to ensure that integer rounding* will take us to the correct final index.*/manual.mode_slot = (((((_rc.channels[_parameters.rc_map_flightmode - 1] - slot_min) * num_slots) + slot_width_half) /(slot_max - slot_min)) + (1.0f / num_slots));if (manual.mode_slot >= num_slots) {manual.mode_slot = num_slots - 1;}}

最后,在commander的主循环中调用set_main_state_rc()函数,其中利用sp_man.mode_slot的值来进行模式切换,当开关切换到POSCTL对应的位置时,执行main_state_transition()函数将新模式写入到internal_state.main_state中,并记录之前的模式和模式切换时间。

2、从mavlink协议进入。

同样在commander的主循环中,当接收到vehicle_command消息时运行handle_command()函数。如果消息的内容是VEHICLE_CMD_DO_SET_MODE,就是根据参数的内容进行模式设定。当参数中的base_mode为CUMTOM且custom_main_mode是PX4_CUSTOM_MAIN_MODE_POSCTL,同样是调用了main_state_transition()函数将新模式写入。

 case vehicle_command_s::VEHICLE_CMD_DO_SET_MODE: {uint8_t base_mode = (uint8_t)cmd->param1;uint8_t custom_main_mode = (uint8_t)cmd->param2;uint8_t custom_sub_mode = (uint8_t)cmd->param3;
.......if (base_mode & VEHICLE_MODE_FLAG_CUSTOM_MODE_ENABLED) {/* use autopilot-specific mode */if (custom_main_mode == PX4_CUSTOM_MAIN_MODE_MANUAL) {/* MANUAL */main_ret = main_state_transition(status_local, commander_state_s::MAIN_STATE_MANUAL, main_state_prev, &status_flags, &internal_state);} else if (custom_main_mode == PX4_CUSTOM_MAIN_MODE_ALTCTL) {/* ALTCTL */main_ret = main_state_transition(status_local, commander_state_s::MAIN_STATE_ALTCTL, main_state_prev, &status_flags, &internal_state);} else if (custom_main_mode == PX4_CUSTOM_MAIN_MODE_POSCTL) {/* POSCTL */main_ret = main_state_transition(status_local, commander_state_s::MAIN_STATE_POSCTL, main_state_prev, &status_flags, &internal_state);......}break;

第二步,导航模式和控制模式的选择。

上一步,在commander中除了切换模式之外,还进行了导航模式和控制模式的设定。

在set_nav_state()函数中设定status->nav_state = vehicle_status_s::NAVIGATION_STATE_POSCTL;

在set_control_mode()函数中根据nva_state的值设定了控制相关的flag,包括:

 case vehicle_status_s::NAVIGATION_STATE_POSCTL:control_mode.flag_control_manual_enabled = true;control_mode.flag_control_auto_enabled = false;control_mode.flag_control_rates_enabled = true;control_mode.flag_control_attitude_enabled = true;control_mode.flag_control_rattitude_enabled = false;control_mode.flag_control_altitude_enabled = true;control_mode.flag_control_climb_rate_enabled = true;control_mode.flag_control_position_enabled = !status.in_transition_mode;control_mode.flag_control_velocity_enabled = !status.in_transition_mode;control_mode.flag_control_acceleration_enabled = false;control_mode.flag_control_termination_enabled = false;break;

并按照一定周期发布了vehicle_control_mode和vehicle_status两个消息。

然后,在navigator的主循环中,根据在commander中设定的导航模式,选择了对应模式的实例。

     case vehicle_status_s::NAVIGATION_STATE_MANUAL:case vehicle_status_s::NAVIGATION_STATE_ACRO:case vehicle_status_s::NAVIGATION_STATE_ALTCTL:case vehicle_status_s::NAVIGATION_STATE_POSCTL:case vehicle_status_s::NAVIGATION_STATE_TERMINATION:case vehicle_status_s::NAVIGATION_STATE_OFFBOARD:case vehicle_status_s::NAVIGATION_STATE_STAB:default:_pos_sp_triplet_published_invalid_once = false;_navigation_mode = nullptr;_can_loiter_at_sp = false;break;

由于这些都是手控模式,因此_navigation_mode = nullptr。也就是不会调用任何导航实例。而是调用了如下代码

     /* if nothing is running, set position setpoint triplet invalid once */if (_navigation_mode == nullptr && !_pos_sp_triplet_published_invalid_once) {_pos_sp_triplet_published_invalid_once = true;_pos_sp_triplet.previous.valid = false;_pos_sp_triplet.current.valid = false;_pos_sp_triplet.next.valid = false;_pos_sp_triplet_updated = true;}if (_pos_sp_triplet_updated) {_pos_sp_triplet.timestamp = hrt_absolute_time();publish_position_setpoint_triplet();_pos_sp_triplet_updated = false;}

实际上由于_pos_sp_triplet.current.valid = false; 函数 publish_position_setpoint_triplet(); 会立即返回,并不会发布提供位置控制期望的position_setpoint_triplet消息出去。

第三步,位置控制的实现。

在mc_pos_control的主循环中首先调用do_control()函数;由于在commander中设定了control_mode.flag_control_manual_enabled = true,进而进入control_manual()函数。对于非手控的模式则进入control_non_manual()函数。

在control_manual()函数中从manual_control_setpoint消息中获取纵横垂向的杆量,并根据参数进行限幅之后给中间变量。然后转换到NED坐标系中。

 math::Vector<2> req_vel_sp_xy;req_vel_sp_xy.zero();float req_vel_sp_z = 0.0f;if (_control_mode.flag_control_altitude_enabled) {/* set vertical velocity setpoint with throttle stick */req_vel_sp_z = -scale_control(_manual.z - 0.5f, 0.5f, _params.alt_ctl_dz, _params.alt_ctl_dy); // D/* reset alt setpoint to current altitude if needed */reset_alt_sp();}if (_control_mode.flag_control_position_enabled) {/* set horizontal velocity setpoint with roll/pitch stick */req_vel_sp_xy(0) = math::expo_deadzone(_manual.x, _params.xy_vel_man_expo, _params.hold_xy_dz);req_vel_sp_xy(1) = math::expo_deadzone(_manual.y, _params.xy_vel_man_expo, _params.hold_xy_dz);/* reset position setpoint to current position if needed */reset_pos_sp();}/* scale requested velocity setpoint to cruisespeed and rotate around yaw */math::Vector<3> vel_cruise(_params.vel_cruise(0),_params.vel_cruise(1),(req_vel_sp_z > 0.0f) ? _params.vel_max_down : _params.vel_max_up);math::Vector<3> req_vel_sp_scaled(req_vel_sp_xy(0), req_vel_sp_xy(1), req_vel_sp_z);/* scale velocity setpoint to cruise speed (m/s) and rotate around yaw to NED frame */math::Matrix<3, 3> R_input_fame;if (_control_mode.flag_control_fixed_hdg_enabled) {R_input_fame.from_euler(0.0f, 0.0f, _yaw_takeoff);} else {R_input_fame.from_euler(0.0f, 0.0f, _att_sp.yaw_body);}req_vel_sp_scaled = R_input_fame * req_vel_sp_scaled.emult(vel_cruise); // in NED and scaled to actual velocity;

根据control_mode设定的flag_control_altitude_enabled和flag_control_position_enabled确定是否在赶回中后保持高度和平面位置(也就是ALTCTL模式和POSCTL模式的作用了)。最后判断是否已经着陆,如果没有着陆就执行control_position()函数,从位置偏差计算速度期望值_vel_sp,并通过消息vehicle_global_velocity_setpoint发布出去,当然还有很多边边角角的复杂计算,需要自己看代码来理解。

回到主循环中,结束了do_control()函数之后,将位置期望和速度期望赋值给_local_pos_sp,并发布消息vehicle_local_position_setpoint。接下来调用generate_attitude_setpoint()函数将姿态角期望写入_att_sp结构体中,并发布vehicle_attitude_setpoint消息。

第四步,姿态控制的实现。

目前还没看完这部分代码,等看完了再更新。

第五步,控制信号的输出。

在PX4IO的主循环中,执行io_set_control_groups()将对应控制组的控制量输出给IO芯片来产生控制电调或者舵机的PWM信号。

PX4飞控手动位置控制POSCTL模式的实现流程相关推荐

  1. PX4位置控制offboard模式说明

    offboard模式的开发及应用 一.px4固件的模式 px4固件支持10几种飞行模式,从代码结构上分析,分为基本模式.自定义模式和自定义子模式. 1.基本模式 基本模式又分为,位置控制模式.自稳模式 ...

  2. 飞控简析-从入门到跑路 第二章PX4的位置控制(1)

    一.前言 首先,我们要清楚的我们的需求,PX4的位置控制需要完成什么样的工作.位置控制需要完成的是,从期望位置得到期望姿态的一个过程,然后把期望姿态传递给姿态控制模块,所以位置控制的输入是期望位置,输 ...

  3. 飞控简析-从入门到跑路 第二章PX4的位置控制(2)

    1.control_auto() 说完control_manual,接下来我们在看看control_auto.control_auto是用来处理自动控制的函数,即把航线任务转换为期望位置.函数位于Mc ...

  4. PX4代码学习系列博客(6)——offboard模式位置控制代码分析(之前转载过,这是第二次转载了)

    我刚刚发现这篇文章去年八月份的时候转载过一次了 https://blog.csdn.net/sinat_16643223/article/details/107874349 转载自:https://b ...

  5. PX4飞控之PWM输出控制

    PX4飞控之PWM输出控制 多旋翼电调如好盈XRotor,DJI通用电调等都支持PWM信号来传输控制信号.常用的400Hz电调信号对应周期2500us,一般使用高电平时间1000us~2000us为有 ...

  6. 汇川伺服电机位置控制模式参数配置

    1. 基本控制参数设置 1)设置位置控制模式 2)绝对值位置线性模式 2.端子输入参数设置 1)将输入端子使能失效 3. 位置控制参数设置 1)将位置来源设置为2:多段位位置指令 4.通信参数设置 1 ...

  7. 伺服速度控制模式接线图_伺服参数设置很重要(位置控制模式、速度控制模式、力矩控制)...

    伺服在自动化设备的组成中占有重要地位.伺服是在其额定转速范围内,属于恒力矩输出.且本身具有多种反馈调节,用来保证伺服的运行精度以及输出力矩的精度.全功能的伺服控制器拥有3多种控制模式,每种控制模式的控 ...

  8. s120面板控制调速_SINAMICS S120 SERVO模式下位置控制与速度控制方式的切换

    图 1 控制系统结构图 从图 1 中看出,通过参数 P2550 和 P1142 的组合设置,可以在两种控制方式之间切换:通过 EPOS 和 P1155 可以对位置和速度进行设定.两种控制方式的 设置组 ...

  9. PX4多旋翼位置控制程序分析 mc_pos_control

    PX4多旋翼位置控制程序分析 mc_pos_control 1. 概述 在本文中,我们将分析PX4程序的基本流程和关键模块. 2. PX4程序流程图 原图大小太大,无法上传(在我主页下载里面找) 3. ...

最新文章

  1. 变频器输出功率_变频器的输出功率该如何选择?
  2. 百度地图同时显示多个路书
  3. 5177. 【NOIP2017提高组模拟6.28】TRAVEL (Standard IO)
  4. Java基础知识回顾--线程
  5. Hybrid框架UI重构之路:一、师其长技以自强
  6. JavaScript技巧[转载]
  7. 网络爬虫-原理篇(一)
  8. 从h264码流中获取图像的宽高---版本2(简洁版)
  9. eclipse注释模板
  10. 7.1 封装(Java包(package)的概念+访问权限修饰符(public/private/protected/default))
  11. ExtJS002Window创建
  12. 安装Adobe Reader出错回滚
  13. 第五章:Flask数据库操作
  14. linux用独显运行steam,修复在Linux系统上与Nvidia不兼容的Steam游戏
  15. 计算机快捷键win,Windows电脑常用的10个Win组合快捷键,你知道多少?
  16. 英语词根研究和单词记忆
  17. linux 公社资料
  18. 用 Python 制作家用防盗工具
  19. translate与rotate
  20. python实现工具exe自动化

热门文章

  1. Go Gin Example
  2. mysql删除函数sql_SQLServer之删除函数
  3. 带薪玩一周游戏,还要涨工资
  4. 易优CMS 聚合关键词seo插件(上权重神器)
  5. 穿上我最爱的格子衫,让别人说去吧! (严肃格子衫选购指南)
  6. 微型计算机原理中中括号是什么意思,微机原理期末
  7. 广和通“投资换市场”,收购标的净利率下滑/车载业务上半年亏损数千万
  8. 网络游戏中的网络编程
  9. web前端-特殊背景自适应结构(上中下)
  10. TSM视频测试——中间篇