Ardupilot 基础入门(库例程学习)---Library Example Sketches

目录

文章目录

  • 目录
  • 摘要
  • 1.库例程草图(Library Example Sketches)
  • 2.理解库例程代码(Understanding the example sketch code)
  • 3.Hal参考(The hal reference)
  • 4.初始化函数和主循环函数(The setup() and loop() functions)
  • 5.AP_HAL_MAIN宏定义(The AP_HAL_MAIN() macro)
  • 6.粗略示例代码(Rough Example code)

摘要



我是平凡的,但不想平庸!梦想还是要有!
本节主要学习ardupilot如何进行基础入门学习飞控代码,最好的就是看库例程代码。



1.库例程草图(Library Example Sketches)



参考网址:Ardupilot 库学习例程


探索代码的第一步是看库里面的例子. 沿袭arduino的传统, 我们在很多库里面都实现了例子. 这些例子就是一个主程序 .cpp文件格式的。

了解ArduPilot中使用的库API和习惯约定,是看懂代码的重要基础.所以使用库里面的例子是一个很好的上手方法。刚开始,您应该阅读、构建和运行以下库的示例草图:



  • libraries/AP_GPS/examples/GPS_AUTO_test
  • libraries/AP_InertialSensor/examples/INS_generic
  • libraries/AP_Compass/examples/AP_Compass_test
  • libraries/AP_Baro/examples/BARO_generic
  • libraries/AP_AHRS/examples/AHRS_Test


图片所示
Ardupilot 基础入门(库例程学习)---Library Example Sketches_第1张图片

比如以下指令会编译并加载AP_Notify例子程序到PixHawk_v5:

采用waf编译


切换路径:cd Desktop/2018-11-19/ardupilot
编译:./waf configure --board fmuv5
下载:./waf build --target examples/ToshibaLED_test --upload

在这里插入图片描述
在这里插入图片描述

使用waf命令能够列出可以构建的例子

终端输入:./waf list | grep 'examples'

Ardupilot 基础入门(库例程学习)---Library Example Sketches_第2张图片


一旦你更新上传了这个示例代码,就可以在终端控制台上查看信息。终端控制台是什么取决于板的类型。在PixHawk板上,它是USB连接器。所以只需连接到USB设备与您最喜爱的串口调试模块(波特率不是很重要)就可以看数据了。说白了就是通过USB连接飞控和电脑上的串口,在串口观察测试的数据就OK!


例如,如果你安装了mavproxy ,就可以在Linux上连接到PixHawk。

使用命令:mavproxy.py --setup --master /dev/serial/by-id/usb-3D_Robotics_PX4_FMU_v2.x_0-if00

使用–setup 选项将 mavproxy 转换为原始串行模式, 而不是经过处理的 MAVLink 模式。这就是你需要的例子草图。
个人感觉这里没必要,直接用串口就可以。




2.理解库例程代码(Understanding the example sketch code)



当您阅读示例草图代码 (如 GPS_AUTO_test 代码) 时, 您会注意到一些最初可能看起来很奇怪的事情:

  • 将 “hal” 变量声明为从外部引用
  • 代码很粗糙,没有很好的注释
  • 都有setup() and loop()函数

这里不依GPS_AUTO_test来进行分析,我采用Led进行分析
Ardupilot 基础入门(库例程学习)---Library Example Sketches_第3张图片
1.hal引用:

const AP_HAL::HAL& hal = AP_HAL::get_HAL(); //声明

2.对象创建:

AP_Notify notify; //创建对象
static ToshibaLED_I2C toshiba_led(1); //选择IIC1

3.初始化:

void setup(void)
{
    // display welcome message
    hal.console->printf("Toshiba LED test ver 0.1\n");

    // initialise LED
    if (toshiba_led.init()) 
    {
        hal.console->printf("Failed to initialise Toshiba LED\n");
    }
    toshiba_led.pNotify = ¬ify;

    // turn on initialising notification
    AP_Notify::flags.initialising = false;
    AP_Notify::flags.save_trim = true;
    AP_Notify::flags.gps_status = 1;
    AP_Notify::flags.armed = 1;
    AP_Notify::flags.pre_arm_check = 1;
}

4.循环函数执行:

void loop(void)
{
    // blink test
    //hal.console->printf("Blink test\n");
    //blink();
    /*
    // full spectrum test
    hal.console->printf("Spectrum test\n");
    full_spectrum();
    */

    // update the toshiba led
    toshiba_led.update();

    // wait 1/50th of a second
    hal.scheduler->delay(20);
}

5.主函数入口:

AP_HAL_MAIN();


3.Hal参考(The hal reference)



每个例程如果想使用 AP_HAL 功能的文件都需要声明 HAL 引用。可以访问 AP_HAL: HAL 对象, 它提供对所有硬件特定功能的访问, 包括将消息打印到控制台、休眠和与 I2C 和 SPI 总线通信。


实际的 hal 变量被隐藏在主板特定的 AP_HAL_XXX 库中。每个文件中的引用只是提供了一个方便的方法来获取 hal。 (备注:hal定义接口,不同的板子来实现


最常用的 hal 函数有:

  • hal.console->printf() 打印字符串
  • AP_HAL::millis()和AP_HAL::micros() 获得启动后的时间
  • hal.scheduler->delay()和hal.scheduler->delay_microseconds() 延迟一段时间
  • hal.gpio->pinMode(), hal.gpio->read() 和hal.gpio->write() 用于访问 GPIO 引脚
  • hal.i2c 用于访问 I2C
  • hal.spi用于访问 SPI

现在, 请在libraries/AP_HAL 目录中查看 HAL 上可用的功能的完整列表。


Ardupilot 基础入门(库例程学习)---Library Example Sketches_第4张图片



4.初始化函数和主循环函数(The setup() and loop() functions)



您会注意到, 每个草图都有一个setup() 函数和loop() 函数。当主板启动时, 将调用setup() 函数。实际的调用来自于每个主板的 hal 内部, 因此 main() 函数被放在 hal 内部, 然后在主板特定的启动完成后调用setup()程序 。


setup() 函数只调用一次,用于初始化库, 并可能打印一个 “hello” 横幅来显示它正在启动。
在setup() 完成后, loop() 函数被连续调用 (通过 AP_HAL 中的主代码)。sketch 的主要工作通常在loop() 函数中。


请注意, 这个setup()/loop() 复杂的板子程序的冰山一角。它会使 ArduPilot 像是单线程, 但实际上有更多的在下面, 并在板上(如 PX4 和 Linux 基板) 实际上会有大量的实时线程启动了。请参见下面关于理解 ArduPilot 线程的部分。



5.AP_HAL_MAIN宏定义(The AP_HAL_MAIN() macro)



在每个sketch 的底部, 你会注意到这样一行额外的代码:

AP_HAL_MAIN();

这是一个 hal 宏, 它生成必要的代码来声明 c++ 主函数, 以及 hal 的任何板级初始化代码。你很少需要担心它是如何工作的, 但是如果你很好奇, 你可以在每个 HAL 的 AP_HAL_XXX 目录中寻找 #define。它通常在 AP_HAL_XXX_Main。(最新代码都在AP_HAL_MAIN.h中

#ifndef AP_MAIN
#define AP_MAIN main
#endif

#define AP_HAL_MAIN() \
    AP_HAL::HAL::FunCallbacks callbacks(setup, loop); \
    extern "C" {                               \
    int AP_MAIN(int argc, char* const argv[]); \
    int AP_MAIN(int argc, char* const argv[]) { \
        hal.run(argc, argv, &callbacks); \
        return 0; \
    } \
    }
#define AP_HAL_MAIN_CALLBACKS(CALLBACKS) extern "C" { \
    int AP_MAIN(int argc, char* const argv[]); \
    int AP_MAIN(int argc, char* const argv[]) { \
        hal.run(argc, argv, CALLBACKS); \
        return 0; \
    } \
    }


6.粗略示例代码(Rough Example code)



您会注意到,示例草图是相当粗糙的,而且注释很少。这是你为代码做出贡献的机会!当您通过示例草图阅读并探索它们如何工作时,向代码添加一些注释来解释API,然后提交一个请求,以便其他人可以从您的学习中受益。

你可能感兴趣的:(ardupilot学习)