无人机飞行模式(Ardupilot和MAVLink协议)(STABILIZE、ALTITUDE HOLD、LOITER、GUIDE、AUTO、LAND、RTL)

理解飞行模式对于能够操纵运行Ardupilot和MAVLink协议的无人系统至关重要。 Ardupilot定义了几种飞行模式。 在本节中,我们介绍最重要且更常见的交易模式。

1、The STABILIZE mode 

稳定模式,在此模式下,无人驾驶系统完全由用户控制。 无人机系统将响应来自用户控制的RC控制器的每个输入,并且由用户自行决定补偿无人机系统产生的任何漂移。
当自动驾驶仪无法以任何其他自主模式控制无人机时,建议用户立即切换到稳定模式以手动控制无人系统。必须注意的是,可以从无人系统中下载数据记录日志文件,通过在任务计划程序中的“图形”选项卡中打开它来分析飞行性能。

2、ALTITUDE HOLD

高度保持:一种更舒适的控制无人系统的模式,用户无需担心为无人系统保持固定的高度,因为自动驾驶仪会自动控制 PID控制器控制无人机的高度。 用户可手动控制无人系统的方向和位置。 与稳定模式相比,对于新手更建议使用此模式,并且不需要GPS,因为它可以使用气压计估算高度。
如下图所示,可以在APM任务计划程序中调整ALT_HOLD模式的PID控制器的设置。用比例控制器保持海拔高度,该比例控制器估计所需海拔高度与实际海拔高度之间的误差并调整垂直加速度。比例增益可以通过地面站进行设置,如下图所示。比例增益须谨慎设置,因为很高的增益会使控制更加激进和不稳定,而非常低的增益会使控制变得更加平稳。非常慢且无响应。

3、LOITER

LOITER:LOITER模式是控制无人系统的一种更易访问的模式,一旦用户不向RC控制器提供输入,它便保持无人系统的当前位置,方向和高度。此模式与STABILIZE模式类似,但是一旦用户将手指从RC操纵杆中拿出,无人机系统将控制其位置,航向和高度。 LOITER模式需要GPS 3D fix才能工作,或需要optical flow。
必须注意,仅当(1)GPS具有3D Lock,(2)HDOP小于2.0时,才可以将无人机设在LOITER模式。因此,此模式需要GPS 3D fix。
为了获得出色的LOITER性能,必须具有(1)GPS Lock,(2)罗盘的受到小的电磁干扰(3)低振动。
可以从Mission Planner地面站或类似的地面站调整PID控制器的增益。 LOITER SPEED代表最大水平速度,单位为cm / s,通常等于500 cm / s(等于5m / s)。默认配置是最大加速度等于LOITER SPEED的一半(即2.5m / s^{2})。
可以通过设置高度,位置和方向(偏航,俯仰和横滚)的PID控制增益,通过地面站来配置LOITER模式的参数。

4、GUIDE

GUIDED模式是必不可少的,并且仅在GPS模式下运行。当无人系统的GPS执行3D fix并被激活时,可以将无人系统发送到通过地面站自动导航到特定的GPS坐标。之所以称为GUIDED模式,是因为无人驾驶系统由用户引导以自动导航到用户选择的特定航路点。
GUIDED模式与GPS结合使用,允许用户将无人系统发送到由其GPS坐标定义的指定航点。仅当GPS具有3D fix功能时,才可以将无人系统武装为GUIDED模式。
通常,在GUIDED模式下,地面站用于将导航航点发送到无人系统进行导航。因此,将遥测设备连接到无人系统和地面站以允许它们之间的远程通信非常重要。
通常,用户需要在GUIDED模式下单击地图上的某个点,然后无人系统会规划其路径并朝目标移动。

5、AUTO

AUTO模式是指自主模式,其中无人系统将遵循预定的任务。 任务是存储在无人系统自动驾驶仪中的一组航点。 当选择“自动”模式时,无人系统将以与存储它们相同的顺序自动到达每个航路点。

6、LAND

LAND模式将迫使无人机着陆。

7、RTL

RTL模式,也称为返回发射,将迫使无人系统返回执行起飞的起始位置。
LAND和RTL模式可用于违反导航安全和地理围栏的情况,例如,可以在自动驾驶仪上编程,如果电池电量低于一定水平,则无人系统需要立即降落或返回起始位置 自动。 这称为GEOFENCE。

class Mode { friend class PayloadPlace; public: // Auto Pilot Modes enumeration enum class Number : uint8_t { STABILIZE = 0, // manual airframe angle with manual throttle ACRO = 1, // manual body-frame angular rate with manual throttle ALT_HOLD = 2, // manual airframe angle with automatic throttle AUTO = 3, // fully automatic waypoint control using mission commands GUIDED = 4, // fully automatic fly to coordinate or fly at velocity/direction using GCS immediate commands LOITER = 5, // automatic horizontal acceleration with automatic throttle RTL = 6, // automatic return to launching point CIRCLE = 7, // automatic circular flight with automatic throttle LAND = 9, // automatic landing with horizontal position control DRIFT = 11, // semi-autonomous position, yaw and throttle control SPORT = 13, // manual earth-frame angular rate control with manual throttle FLIP = 14, // automatically flip the vehicle on the roll axis AUTOTUNE = 15, // automatically tune the vehicle's roll and pitch gains POSHOLD = 16, // automatic position hold with manual override, with automatic throttle BRAKE = 17, // full-brake using inertial/GPS system, no pilot input THROW = 18, // throw to launch mode using inertial/GPS system, no pilot input AVOID_ADSB = 19, // automatic avoidance of obstacles in the macro scale - e.g. full-sized aircraft GUIDED_NOGPS = 20, // guided mode but only accepts attitude and altitude SMART_RTL = 21, // SMART_RTL returns to home by retracing its steps FLOWHOLD = 22, // FLOWHOLD holds position with optical flow without rangefinder FOLLOW = 23, // follow attempts to follow another vehicle or ground station ZIGZAG = 24, // ZIGZAG mode is able to fly in a zigzag manner with predefined point A and point B SYSTEMID = 25, // System ID mode produces automated system identification signals in the controllers AUTOROTATE = 26, // Autonomous autorotation AUTO_RTL = 27, // Auto RTL, this is not a true mode, AUTO will report as this mode if entered to perform a DO_LAND_START Landing sequence TURTLE = 28, // Flip over after crash // Mode number 30 reserved for "offboard" for external/lua control. // Mode number 127 reserved for the "drone show mode" in the Skybrush // fork at https://github.com/skybrush-io/ardupilot }; } 现在定义mode *flightmode。怎么获取当前模式是哪个序号
03-08
<think>好的,用户的问题是关于如何从C++代码中定义的Mode类中获取当前模式对应的序号。用户给出的代码片段中有一个枚举类Number,里面列出了各种飞行模式及其对应的数值。现在有一个指向flightmode对象的指针,需要知道如何获取当前模式的序号。 首先,我需要理解用户提供的代码结构。Mode类有一个公有的枚举类Number,其中每个枚举值对应一个飞行模式的序号。例如,STABILIZE对应0,ACRO对应1,依此类推。此外,Mode类有一个友元类PayloadPlace,这可能意味着PayloadPlace可以访问Mode的私有成员。 用户定义了一个flightmode指针,可能是某个Mode类的实例。要获取当前模式的序号,需要访问该对象的当前模式枚举值,并将其转换为整数。 接下来,我需要考虑C++中枚举类的特性。枚举类(enum class)的类型安全特性使得其枚举值不会隐式转换为整数,因此必须使用static_cast进行显式转换。例如,如果有一个变量mode_number是Mode::Number类型,可以通过static_cast<uint8_t>(mode_number)来获取对应的整数值。 但是,如何从flightmode对象中获取当前的Mode::Number值呢?这取决于Mode类是否提供了获取当前模式的方法。例如,Mode类可能有一个成员函数返回当前的Number枚举值,如get_mode_number(),或者有一个成员变量直接存储当前模式。由于用户提供的代码片段中,Mode类的定义并不完整,特别是没有看到成员函数或变量,我需要做一些假设。 在Ardupilot等自动驾驶仪的实际代码中,通常会有类似get_mode()的方法来返回当前的飞行模式。假设Mode类有一个成员函数返回当前的Number枚举值,那么调用该函数即可。例如: Mode::Number current_mode = flightmode->get_current_mode_number(); uint8_t mode_number = static_cast<uint8_t>(current_mode); 如果Mode类没有这样的方法,可能需要直接访问其成员变量。例如,如果有一个成员变量current_mode,则可能需要: uint8_t mode_number = static_cast<uint8_t>(flightmode->current_mode); 但这种情况可能需要友元类或公共访问权限。由于PayloadPlace是Mode的友元类,而用户可能不在PayloadPlace类中,所以直接访问成员变量可能不可行,除非用户在自己的代码中也有友元关系。 另一种可能性是,flightmode对象可能有一个转换为枚举值的方法,或者通过其他接口获取模式序号。例如,可能有一个返回整数的方法,或者通过某个函数间接获取。 假设用户无法修改Mode类,并且需要从外部获取当前模式的序号,可能需要依赖Mode类提供的公共接口。例如,Ardupilot中可能有类似于mode->number()的方法来返回枚举值。 因此,正确的步骤应该是: 1. 确定Mode类中是否有公共方法可以获取当前的Number枚举值。例如,get_mode_number()。 2. 调用该方法获取当前模式的枚举值。 3. 使用static_cast将枚举值转换为uint8_t类型,得到对应的序号。 如果用户提供的Mode类没有这样的方法,可能需要检查Mode类的实际实现,或者是否有其他方式可以访问模式序号。此外,考虑到友元类PayloadPlace,如果用户的代码是在PayloadPlace类内部,可能可以直接访问Mode的私有成员,但这种情况较为特殊。 综上所述,假设Mode类有一个返回当前模式枚举值的公共方法,那么正确的代码应该是: uint8_t current_mode_number = static_cast<uint8_t>(flightmode->get_current_mode()); 如果flightmode是指向Mode类的指针,并且get_current_mode()是Mode类的一个公共成员函数,返回Mode::Number类型的值。 如果用户无法确定是否存在这样的方法,可能需要查阅Mode类的完整定义或相关文档,以确定正确的访问方式。此外,在Ardupilot的实际代码中,通常会有模式相关的处理函数,例如AP_Mission库中的方法,或者通过其他接口获取当前模式。 最后,需要提醒用户注意,如果flightmode指针未正确初始化或为空,访问其成员会导致未定义行为,因此在实际代码中应进行空指针检查。</think>要获取当前飞行模式对应的枚举序号,可以按照以下步骤操作: 1. 首先确保`flightmode`指针有效且已初始化 2. 通过类型转换将枚举值转为整数 3. 推荐使用安全的强制类型转换方法 实现代码示例: ```cpp // 假设有获取当前模式的成员函数 Mode::Number current_mode = flightmode->get_current_mode(); // 将枚举值转换为对应的uint8_t序号 uint8_t current_mode_number = static_cast<uint8_t>(current_mode); // 使用时可以直接比较枚举值 if (current_mode == Mode::Number::AUTO) { // 处理自动模式逻辑 } // 或者通过转换后的整数值比较 if (current_mode_number == 3) { // 3对应AUTO模式 // 处理自动模式逻辑 } ``` 关键点说明: 1. 枚举类特性:使用`enum class`定义的是强类型枚举,不会隐式转换为整数 2. 类型转换:必须使用`static_cast<uint8_t>`显式转换 3. 模式比较:推荐直接比较枚举值而非整数,增强代码可读性 4. 实际应用:在ArduPilot代码中通常通过`control_mode`宏获取当前模式 注意事项: - 实际代码中可能需要通过`hal.console->printf()`输出调试信息 - 在飞行控制代码中,模式切换需要严格遵循状态机转换规则 - 某些模式(如TURTLE模式)需要特殊硬件支持才能激活 建议在ArduPilot开发环境中使用以下调试方法: ```cpp // 打印当前模式名称序号 hal.console->printf("Current Mode: %s (%d)", flightmode->name(), static_cast<uint8_t>(flightmode->mode_number())); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

autotian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值