自定义飞行模式

news/2024/11/7 20:48:29/

添加自定义模式

本文主要参考APM官网
(https://ardupilot.org/dev/docs/apmcopter-adding-a-new-flight-mode.html)
以及怒飞垂云的博客
(http://www.nufeichuiyun.com/?p=277)

APM的代码量非常大,想要完全搞明白不太可能,快速入门的方法就是仿照着大牛们写过的程序,自己试着写一下,比如说我现在要添加一个最简单的矩形航线,我们可以先查看github上所提供的所有模式,然后比较一下,看自己想添加的模式和哪个相近,我这里添加的模式就可以仿照circle这个模式来写。

1 修改飞行模式流程(以ArduCopter为例)

下面是ArduCopter的架构视图
在这里插入图片描述

下图显示了手动模式(例如Stabilize, Acro, Drift)的体系结构

在这里插入图片描述

下图显示了自主模式(即RTL,Guided,Auto)的体系结构

在这里插入图片描述

在mode.h中为该模式定义一个新类。复制一个类似的现有模式的类定义并仅更改类名称(即,将“类ModeStabilize”复制并重命名为“类ModeNewMode”)可能是最容易的。
新类应从Mode类继承 run()和init().所以说每个类的定义大致如下:

public:// inherit constructorusing Mode::Mode;bool init(bool ignore_checks) override;void run() override;protected:const char *name() const override { return "NEWMODE"; }const char *name4() const override { return "NEWM"; }

这些是必须有的。

还有一些返回true / false的简单方法,您可能想覆盖该控制功能,例如是否可以在新模式下布防Copter:

bool requires_GPS() const override { return false/true; }
bool has_manual_throttle() const override { return true/false; }
bool allows_arming(bool from_gcs) const override { return true; };
bool is_autopilot() const override { return false; }

其中requires_GPS()和has_manual_throttle()两个函数返回值依据飞行模式来确定,一般情况下手动模式(例如Stabilize, Acro)是不需要GPS但需要油门。
一般情况下自动模式(RTL, Guided, Auto)需要GPS不需要油门。
当然某些是除外的,这里笔者是为了方便理解这样归类的。

1.1 init()函数

基于类似的模式(例如mode_stabilize.cpp 或mode_circle.cpp)创建一个新的mode_ <新飞行模式> .cpp文件 。这个新文件可能应该实现init()将在飞机首次进入模式时调用的方法。如果飞机可以进入该模式,则此函数应返回true,否则返回false。以下是mode_rtl.cpp的init方法的摘录,其中显示了除非设置了原始位置,否则飞机无法进入RTL模式。

// circle_init - initialise circle controller flight mode
bool Copter::ModeCircle::init(bool ignore_checks)
{if (copter.position_ok() || ignore_checks) {pilot_yaw_override = false;// initialize speeds and accelerationspos_control->set_speed_xy(wp_nav->get_speed_xy());pos_control->set_accel_xy(wp_nav->get_wp_acceleration());pos_control->set_speed_z(-get_pilot_speed_dn(), g.pilot_speed_up);pos_control->set_accel_z(g.pilot_accel_z);// initialise circle controller including setting the circle center based on vehicle speedcopter.circle_nav->init();return true;}else{return false;}
}
}

1.2 run()函数

以下是mode_stabilize.cpp的更新方法(称为每秒400次)的摘录,该更新方法对用户的输入进行解码,然后将新目标发送给姿态控制器。

void ModeStabilize::run()
{// convert pilot input to lean anglesfloat target_roll, target_pitch;get_pilot_desired_lean_angles(target_roll, target_pitch, copter.aparm.angle_max, copter.aparm.angle_max);// get pilot's desired yaw ratefloat target_yaw_rate = get_pilot_desired_yaw_rate(channel_yaw->get_control_in());// code that sets motor spool state omitted// call attitude controllerattitude_control->input_euler_angle_roll_pitch_euler_rate_yaw(target_roll, target_pitch, target_yaw_rate);// output pilot's throttleattitude_control->set_throttle_out(get_pilot_desired_throttle(), true, g.throttle_filt);

2 实战

笔者根据APM官网所给的教程以及参考开头提到的博客自己设计了两个简单的飞行模式,一个是按照举行路线飞,另一个是按照正六边形路线飞。以下是具体实现步骤:

1先复制一份Circle.cpp

(1)将mode_Circle.cpp文件复制,在这个代码的基础上修改,生成自己的模式。
(2)先找到mode_Circle.cpp文件,可以根据这里的函数查看它是在哪里定义的(Ctrl+f3),复制一份放在要仿照的class的下面,将class的名称改为自定义的名称:
在这里插入图片描述
在这里插入图片描述
然后按照自己的需求修改成员变量和成员函数。

2修改函数

然后返回到Rectangle.cpp,将modeCircle全部替换成ModeRec,删减及修改函数。
下面是mode_Rec.cpp

#include "Copter.h"/** Init and run calls for guided flight mode*///init()和run()是两个必备的// guided_init - initialise guided controller
//初始化时应该计算飞行路径
bool Copter::ModeRec::init(bool ignore_checks)
{if (copter.position_ok() || ignore_checks) {// initialise yawauto_yaw.set_mode_to_default(false);//将当前航点清零path_num=0;//产生要飞行的路径generate_path();// start in position control mode//产生路径之后飞控就会启动位置控制引导//飞机按照规划路径走pos_control_start();return true;}else{return false;}
}void Copter:: ModeRec::generate_path()
{float radius_cm=1000.0;//停止点作为第0航点wp_nav->get_wp_stopping_point(path[0]);path[1]=path[0]+Vector3f(1.0f,0,0)*radius_cm;path[2]=path[1]+Vector3f(0.0,-1.0f,0.0)*radius_cm;path[3]=path[2]+Vector3f(-2.0f,0.0,0.0)*radius_cm;path[4]=path[3]+Vector3f(0.0,2.0f,0.0)*radius_cm;path[5]=path[4]+Vector3f(2.0f,0.0,0.0)*radius_cm;path[6]=path[1];
}// initialise guided mode's position controller
void Copter::ModeRec::pos_control_start()
{// initialise waypoint and spline controller//航点导航库的初始化wp_nav->wp_and_spline_init();// no need to check return status because terrain data is not used//将当前航点设为目标停止点wp_nav->set_wp_destination(path[0], false);// initialise yaw//航向控制设为默认auto_yaw.set_mode_to_default(false);
}// guided_run - runs the guided controller
// should be called at 100hz or more
void Copter::ModeRec::run()
{if(path_num<6){//判断是否到达目标航点if(wp_nav->reached_wp_destination()){//到达目标航点,切换到下一行点path_num++;wp_nav->set_wp_destination(path[path_num],false);}}pos_control_run();}// guided_pos_control_run - runs the guided position controller
// called from guided_run
void Copter::ModeRec::pos_control_run()
{// if not auto armed or motors not enabled set throttle to zero and exit immediatelyif (!motors->armed() || !ap.auto_armed || !motors->get_interlock() || ap.land_complete) {zero_throttle_and_relax_ac();return;}// process pilot's yaw inputfloat target_yaw_rate = 0;if (!copter.failsafe.radio) {// get pilot's desired yaw ratetarget_yaw_rate = get_pilot_desired_yaw_rate(channel_yaw->get_control_in());if (!is_zero(target_yaw_rate)) {auto_yaw.set_mode(AUTO_YAW_HOLD);}}// set motors to full rangemotors->set_desired_spool_state(AP_Motors::DESIRED_THROTTLE_UNLIMITED);// run waypoint controllercopter.failsafe_terrain_set_status(wp_nav->update_wpnav());// call z-axis position controller (wpnav should have already updated it's alt target)pos_control->update_z_controller();// call attitude controllerif (auto_yaw.mode() == AUTO_YAW_HOLD) {// roll & pitch from waypoint controller, yaw rate from pilotattitude_control->input_euler_angle_roll_pitch_euler_rate_yaw(wp_nav->get_roll(), wp_nav->get_pitch(), target_yaw_rate);} else if (auto_yaw.mode() == AUTO_YAW_RATE) {// roll & pitch from waypoint controller, yaw rate from mavlink command or mission itemattitude_control->input_euler_angle_roll_pitch_euler_rate_yaw(wp_nav->get_roll(), wp_nav->get_pitch(), auto_yaw.rate_cds());} else {// roll, pitch from waypoint controller, yaw heading from GCS or auto_heading()attitude_control->input_euler_angle_roll_pitch_yaw(wp_nav->get_roll(), wp_nav->get_pitch(), auto_yaw.yaw(), true);}
}

这里主要增加了generate()这个函数,用来产生要飞行的路径,起始点的位置为path[0],且这也是停止点的位置。不同的飞行路径只需要根据几何关系修改generate_path()即可。
例如,若要规划一个正六边形的路径只需要改成下面这样即可:

void Copter:: ModeSixB::generate_path()
{float radius_cm=1000.0;//停止点作为第0航点wp_nav->get_wp_stopping_point(path[0]);path[1]=path[0]+Vector3f(cosf(radians(30)),-sinf(radians(30)),0)*radius_cm;path[2]=path[0]+Vector3f(0.0,-1.0f,0.0)*radius_cm;path[3]=path[0]+Vector3f(-cosf(radians(30)),-sinf(radians(30)),0)*radius_cm;path[4]=path[0]+Vector3f(-cosf(radians(30)),sinf(radians(30)),0)*radius_cm;path[5]=path[0]+Vector3f(0.0,1.0f,0.0)*radius_cm;path[6]=path[0]+Vector3f(cosf(radians(30)),sinf(radians(30)),0)*radius_cm;path[7]=path[1];
}

这样还没完,还需要其他的修改。接下来要考虑如何切换飞行模式,其他的飞行模式都在mode.cpp中有所定义,以case形式。如下图所示:
在这里插入图片描述

在最下面添加case REC: 下面的名称仿照上面的,查找上面的FOLLOW的定义:
在这里插入图片描述
这样就可以了。我们还以FOLLOW为例,我们还需要查看mode_follow的定义,依旧按住F3跳到定义出,可以看出这是在copter.cpp找那个定义的:
在这里插入图片描述
我们只需要在下面跟着定义一下名称。
你以为这样就完了么?不,还差最后一步,我们需要在地面站中显示出这个模式,我们需要在GCS_Mavlink.cpp中 switch…case…一下这个模式,如下图所示:
在这里插入图片描述
这样就完成了所有的步骤。效果图如下:
在这里插入图片描述


http://www.ppmy.cn/news/644150.html

相关文章

计算机连接网络是飞行模式怎么办,电脑wifi界面只有飞行模式怎么办

大家有没有遇到过电脑用得好好的突然之间就没有了WiFi网络了&#xff0c;导致工作和游戏都完成不了&#xff0c;打开WiFi网络界面发现什么都没有了&#xff0c;只有一个飞行模式&#xff0c;即使重启也无法修复。在网上查找多种方法后&#xff0c;发现修改注册表可以修复了&…

“飞行模式”与“离线模式”

“飞行模式”变“离线模式” 2010-03-25 04:43:00 来源: 华商网-华商报(陕西西安) 不久前&#xff0c;国内某航班上一位乘客由于使用手机“飞行模式”玩游戏&#xff0c;结果被罚了2000元&#xff0c;此事引发手机用户对“飞行模式”的重新关注。 厂商对策 “飞行模式”因误导…

判断WIFI打开关闭,飞行模式打开关闭

//飞行模式打开与关闭 int isAirplaneMode Settings.System.getInt(context.getContentResolver(),Settings.System.AIRPLANE_MODE_ON,0); //0关闭&#xff0c;1开启 Log.e("motejia", "onCreate: FLY"isAirplaneMode ); //WIFI模式的打开与关闭 ConfigTe…

adb命令开关android系统飞行模式

1.打开飞行模式&#xff1a; adb shell settings put global airplane_mode_on 1 2.关闭飞行模式 adb shell settings put global airplane_mode_on 0 3.打开wifi adb shell svc wifi enable4.关闭wifi adb shell svc wifi disable 5.特别说明 因为adb shell命令打开飞行…

电脑无法关闭飞行模式,按钮显示灰色怎么办?

方法优先级&#xff1a;自上而下 方法一&#xff1a;重启电脑 方法二&#xff1a;网络重置 点“立即重置”后&#xff0c;系统会在5分钟之后重启。重启后&#xff0c;网络的所有自定义设置会被删除&#xff0c;网络设置会被重置&#xff0c;其中包括飞行模式。 方法三&#…

Win10只有飞行模式,没有WLAN图标

以前都是8点多开电脑&#xff0c;今天有点冷&#xff0c;冻醒了&#xff0c;6点多跑起来 结果死活连不上网络 压根没有wifi的图标&#xff0c;就一个飞行模式。 我就纳闷了&#xff0c;win10的更新我早就关掉了&#xff0c;电脑用了几年都没变故&#xff0c;怎么今天还出问题…

(15)为Copter添加新的飞行模式

本节涵盖了如何创建一个新的高级飞行模式的基础知识(即相当于 Stabilize、Loiter 等)。 作为参考,下图提供了 Copter 架构的高层次视图。 1) 为新模式取一个名字,并把它添加到 modes.h 中 control_mode_t 枚举的底部,就像下面添加的"NEW_MODE"。 // A

飞行模式到底管用吗?

"飞行模式"到底管用吗&#xff1f;Comments>> 苏椰 发表于 2010-03-14 19:59 最近有新闻报道&#xff0c;在大连到浦东的一架飞机上&#xff0c;某男不顾劝阻&#xff0c;偏要把手机开至“飞行模式”&#xff0c;而不关闭电源。结局是悲剧的&#xff1a;他被罚…