四轴 - - 程序 - 学习 - apm(px4 - - ardupoilot - - apm - )(1)

更新时间:2023-09-09 13:45:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

四旋翼飞行器搭建教程

(译自————加里斯.欧文 )

本文将带你通过建立自己的飞行控制器(飞空软件),同时教你工作的具体细节。这些信息很难找到,特别是那些本身就不是航天工程师的人!就我个人而言,我用了六个月,因为我花费了太多的时间查找bug和调试bug,但通过这篇文章你可以短期收获同样的经验。我会教你避开陷阱,这样你就不会像我一样浪费时间。

第一个关键是你对硬件的选择。我选择从零开始建立自己系统,在这一阶段的时候我都不知道RC(remote controlled 遥控; radio coding 无线电编码; )和飞行器是如何飞行的,这是一个巨大错误。开始我以为,通过自行购买附加电路,芯片和传感器能省很多钱,结果最终我花了一大笔钱!放过自己吧,直接去购买ardupilot 2.5控制板,组装你的直升机,了解遥控,了解飞行原理,然后回到这里。这个板子本质上是只是一个连有一些传感器Arduino(开源主控板,可查http://baike.http://www.wodefanwen.com//view/1268436.htm?fr=aladdin),和我们将在这篇文章介绍的程序——我们自己编写的。你得将所有东西连接起来,你的四旋翼飞机才能得飞:当然你也得会用优秀的arducopter软件。

本项目(ardupilot)由3D Robotics 提供赞助,这意味着他们销售所设计的硬件获利,并将所得利润回馈社区。该软硬件是完全开源的,所有人可以免费复制下载。你可以直接从他们那里购买,或者从Hobbyking (named HKPilot) and RCTimer (named ArduFlyer).购买相同的拷贝件。

在这篇文章中,我将假定您有ardupilot硬件——其本质上上是附传感器Arduino。如果你选择忽视我的建议,并且建立自己的硬件,或使用Arduino电路板,那么您需要更换的底层代码(HAL库)。我也会以为你在X配置(x型四旋翼),+ / X(两种四旋翼配置)和六/八 旋翼飞行器之间切换(只是不同的电机的组合),配置的改变不会让它在本文有任何实质性的区别。理想的情况是,你已经飞行过加载了arducopter代码的四旋翼,因此你应该将电机连接如下所示的位置和旋转方向。

我也要假设你有一些arduino的经验,或至少是C / C + +的经验。Arduino库不是特别智能的或适合,所以我们将使用一些更加合适的的ardupilot库。然而,我们会尽量少使用、最小幅度的使用,以提供DIY式解决方案的支持(这就是为什么你在这里毕竟)。我们将要使用的第一和主要库是ardupilot硬件抽象层(HAL)库。这个库试图隐藏了底层的区别,例如你如何读取和写入引脚和其它一些东西——其优势是,软件可移植到新的硬件,只需更换硬件抽象层。在ardupilot的情况下,有两个硬件平台,APM和PX4,每一个都有自己的底层库允许ardupilot代码运行。如果您稍后决定在Raspberry Pi上运行你的代码,你只需要改变硬件层代码。

硬件层是由如下几个部分组成:

RCInput无线输入——阅读RC无线电rc input -。

RCOutput无线输出——用于控制电动机和其它输出rcoutput -。 Scheduler计划表——运行特定的任务在固定时间间隔调度程序-。 console控制台——提供访问串行端口。

I2C,SPI——总线驱动程序(用于连接传感器小电路板网络)

GPIO —— 一般目的的输入/输出——允许直接访问Arduino引脚,但是在我们的案例中,主要的发光二极管

如何下载:你需要下载Arduino的IDE ardupilot版。还需要将库文件放在你的延伸文件夹中。还要确保你选择你的板类型像Arduino的菜单这样:

Reading the Radio Inputs

读取无线电输入

我们的飞行控制系统要读取无线电输入信号(飞行指令),测量四旋翼的实时的姿态(偏航/俯仰/滚动),改变电机的转速——以适应四旋翼按照我们所期望的方式飞行。所以让我们开始通过无线电开始学习。

RC接收机有几个输出,有好几个通道(或称为棒/开关/旋钮)。无线电输出的50Hz脉冲,这个脉冲的宽度是由无线电发射机的摇杆位置决定的。通常情况下,脉冲持续1000us到2000us长并有18000us到19000us的间隙,所以表示0的油门 会产生一个1000us的脉冲,表示完全的油门 则有2000us长。可悲的是,大多数的接收机是不准确的,我们通常要测量每个杆位的最小或最大值脉冲宽度(这我们接下来将要做的)。

Ardupilot的底层库,为我们做了测量这些脉冲宽度的痛苦工作。如果你自己编写这些代码,你需要中断其他工作并用定时器来测量无线电信号——analogread Arduino不适合做这项工作,因为它占用了处理器全部的计算容量,虽然它可以测量,但是同时也阻止我们其他事。(即 Arduino是单线程软件,无法同时做两项工作)实现一个测量信号的工作并不难,让这种程序持续1个小时甚至更长是很普通的事,我们不是只做这么简单的程序。

下面是一些使用APM 底层库,测量通道“值”的代码的简单例子。通道“值”就是测量毫秒级的脉冲宽度。 #include #include #include #include #include #include #include #include const AP_HAL::HAL& hal = AP_HAL_AVR_APM2; // Hardware abstraction layer void setup() { } void loop() { uint16_t channels[8]; // array for raw channel values // Read RC channels and store in channels array hal.rcin->read(channels, 8); // Copy from channels array to something human readable - array entry 0 = input 1, etc. uint16_t rcthr, rcyaw, rcpit, rcroll; // Variables to store rc input rcthr = channels[2]; rcyaw = channels[3]; rcpit = channels[1]; rcroll = channels[0]; hal.console->printf_P( PSTR(\ rcthr, rcyaw, rcpit, rcroll); hal.scheduler->delay(50); //Wait 50ms }

AP_HAL_MAIN(); // special macro that replace's one of Arduino's to setup the code (e.g. ensure loop() is called in a loop).

创建一个新的草稿脚本,并将该脚本上传到Ardupilot 硬件上。使用串行记录仪纪录下每个通道的最大和最小值。(同时将脉冲调至极限)

现在让我们来衡量脉冲的“值”,以显示他们所含有的意义。我们要使用一种称为Map的功能,这是一种确定一个数值在某一区间将其判读为另一“值”的功能。例如,有一个50的数值,在0——100之间,而我们想要将他放入0到500这个区间来衡量,Map的功能将会定义其为250,并返回250这个值。

Map功能会在你引用并定义(#include&defines)之后被启用(从Arduino库中引用) long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } 这样使用Map功能:

result = map(VALUE, FROM_MIN, FROM_MAX, TO_MIN, TO_MAX). 你会感到仍然没有接触到 油门,毫无疑问你会对于自己没有参与建立油门的判读而感到高兴,这个阀值是由电调生成的(如果你是按照我的建议做的)。俯仰和翻滚在正负45度之间会被测量,当然你也可以设定为正负150度。

{ // *** MINIMUM THROTTLE TO DO CORRECTIONS MAKE THIS 20pts ABOVE YOUR MIN THR STICK ***/ long pitch_output = pids[PID_PITCH_RATE].get_pid(gyroPitch - rcpit, 1); long roll_output = pids[PID_ROLL_RATE].get_pid(gyroRoll - rcroll, 1); long yaw_output = pids[PID_YAW_RATE].get_pid(gyroYaw - rcyaw, 1); hal.rcout->write(MOTOR_FL, rcthr - roll_output - pitch_output); hal.rcout->write(MOTOR_BL, rcthr - roll_output + pitch_output); hal.rcout->write(MOTOR_FR, rcthr + roll_output - pitch_output); hal.rcout->write(MOTOR_BR, rcthr + roll_output + pitch_output); } else { // MOTORS OFF hal.rcout->write(MOTOR_FL, 1000); hal.rcout->write(MOTOR_BL, 1000); hal.rcout->write(MOTOR_FR, 1000); hal.rcout->write(MOTOR_BR, 1000); for(int i=0; i<6; i++) // reset PID integrals whilst on the ground pids[i].reset_I(); }

现在在你的手中要将油门提高20%,然后向前/向后,向左/向右偏转四旋翼,并保证螺旋桨的速度增加或减少。如果四旋翼向一边倾斜, 那一边的螺旋桨就要加速相反一边的则要减速。如果不这样,改变相应的电机信号,(例如,如果俯仰角是错的,在错误的俯仰角之前没有改变信号,四旋翼就会翻滚)。

你可以这样测试你选择的数据,同步你的PID数据,用绳子将四旋翼固定在一个轴上,测试没一个轴的翻转。这是一个非常有用的经验去了解PID是如何运作的,但是不是必须的。这是我评定合适PID数据的示范——我让他以50度每秒翻转。

Video: Rate PIDs only with quad fixed on one axis

四旋翼固定在一个轴线上,测试合适PIDs数据。

现在,我们需要添加偏航(左右航向)的支持。正如你所知,两侧的电机向相反的方向旋转给我们偏航的控制。所以我们要成对的增速或减速,以维持航向正常。

hal.rcout->write(MOTOR_FL, rcthr - roll_output - pitch_output -yaw_output); hal.rcout->write(MOTOR_BL, rcthr - roll_output + pitch_output + yaw_output); hal.rcout->write(MOTOR_FR, rcthr + roll_output - pitch_output + yaw_output); hal.rcout->write(MOTOR_BR, rcthr + roll_output + pitch_output - yaw_output);

这是一个更难的测试项目。你需要提高油门这样才能使它盘旋一点。如果偏航的信号错了四旋翼将自旋。

现在你能让你的四旋翼能够离地几秒钟。如果你觉得适应ACRO模式,你甚至可以驾驶它-请记住这是ACRO模式,不是在arducopter在那里进行自动找平。

如果你的四旋翼飞的偏软,或振荡,那么你需要调整你的Kp常数。如果偏软或如果振荡或如果偏硬,说明你使用了错误的方式 ,尝试打印出PID输出电机命令以纠错,和转动的调试四旋翼(不带电池的连接)。

Stablilised Control

稳定控制

稳定模式与速率模式相近, 只不过其代码高于速率模式:

现在 ,操作手杆位希望四旋翼保持某一个角度,而不是旋转模式。所以我们可以说,如果操作手的杆位是在中心的话,四旋翼现在应该保持20度的俯角,然后:

error = desiredAngle - actualAngle = 0 - 20 = -20

差=希望的角度-实际角度=0—20=—20

在这个实例中,我们需要将差与Kp相乘,得到我们需要的角速率。你一定能注意到,Kp值因为稳定的原因被设定为4.5。所以,如果我们我有-20度的角差的话,就要输出-20*4.5=-90的PID(负数仅意味着方向)。这意味着四旋翼会接收一个每秒-90度的速率恢复水平位置——我们只需要将这个数据早先设置在控制器里。我们的四旋翼会开始倾向水平了,角度差会减少,输出目标速率也会减少,所以四旋翼开始高速,然后低速的回复到水平位置正是我们所希望的。

// our new stab pids float pitch_stab_output = constrain(pids[PID_PITCH_STAB].get_pid((float)rcpit - pitch, 1), -250, 250); float roll_stab_output = constrain(pids[PID_ROLL_STAB].get_pid((float)rcroll - roll, 1), -250, 250); float yaw_stab_output = constrain(pids[PID_YAW_STAB].get_pid((float)rcyaw - yaw, 1), -360, 360); // rate pids from earlier long pitch_output = (long) constrain(pids[PID_PITCH_RATE].get_pid(pitch_stab_output - gyroPitch, 1), - 500, 500); long roll_output = (long) constrain(pids[PID_ROLL_RATE].get_pid(roll_stab_output - gyroRoll, 1), -500, 500); long yaw_output = (long) constrain(pids[PID_YAW_RATE].get_pid(yaw_stab_output - gyroYaw, 1), -500, 500);

现在你的四旋翼应该能够悬停,虽然它可能不稳定或振荡。所以,如果它飞行的动作不太大——现在是时候调整那些PID,主要集中在利率(KP特别)-所指出应当可以。对于速率I级的主题,设定使他们有~ 1俯仰/滚动角和无偏航角。

请注意,偏航并没有像预期的那样,偏航被你的摇杆锁定——所以你会发现摇杆向左偏转45度 航向也会左四旋转45度,当你回到摇杆中心,四旋翼也会返回其偏航中心。目前我们的代码就是这样的,我们可以去除航向稳定控制器,让摆杆直接控制偏航率,但同时如果又一阵风向四旋翼袭来,它将偏航可能漂移而且不会恢复正常。所以,当操作手使用偏航摇杆时我们的直接进入速度控制器,当他放下时,我们使用稳定控制器锁航向以防他偏离。

由于偏航值从180到180,我们需要一个区间定义,横摆角达到181或-181度时将执行一个保护操作。所以在你的代码定义的顶部:

#define wrap_180(x) (x < -180 ? x+360 : (x > 180 ? x - 360: x))

如果你仔细查看你会发现,如果他是-180度,就加360度;如果他是180度就加-360度,我们就让他这样做。

定义全局或稳定变量 float yaw_target = 0; 现在在主loop函数里,我们需要设定操作手控制摇杆时航向是速率控制,无操作时是稳定控制—锁定航向。

float yaw_stab_output = constrain(pids[PID_YAW_STAB].get_pid(wrap_180(yaw_target - yaw), 1), -360, 360); if(abs(rcyaw) > 5) { // if pilot commanding yaw yaw_stab_output = rcyaw; // feed to rate controller (overwriting stab controller output) yaw_target = yaw; // update yaw target } 当四旋翼在地面上没有油门时,你现在也可以设定你的航向目标。 你也可以将其与不分也这么做。

是的,现在航向应该表现正常。但如果你注意的话,你可能会注意到,偏航过几十秒会抖动一下。这可能不会打扰你了,原因是发生是因为虽然你的偏航摇杆还是在中位,无线电抖动则使四旋翼并不总是收到0信号 -它在真值之间抖动造成偏航改变。此外,该mpu6050的偏航传感器也会随着时间的推移(1-2deg /秒)而漂移——你需要用指南针来补偿这种漂移(如果你真的在乎修复它,大多数人没有注意到)。

Final Product - video and full code 最终产品—视频和全部代码

恭喜,你已经一个多直升机创建你的第一个飞行控制器代码!你会发现它比标准的arducopter代码更具挑战性,很多,这是因为arducopter有很多对操作员的输入处理使它更容易飞。提高你的油门到80%和四旋翼将如火箭般直飞向天空,比arducopter实现的更快。警告-不要提高你的油门太接近100%,以留有空间使得控制器能够改变电机速度使得它恢复水平和翻转(你相当容易的实现一个自动降低油门的程序)。

本文来源:https://www.bwwdw.com/article/phnh.html

Top