图书馆草图示例

自己探索代码的第一步是使用库的示例草图。按照 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

例如,下面将在 Pixhawk 上构建并安装 AP_GPS 示例草图:

cd $ARDUPILOT_HOME # ArduPilot 资源库的顶层 ./waf configure --board=Pixhawk1 ./waf build --target examples/INS_generic --upload

waf 可以列出它可以构建的示例:

cd $ARDUPILOT_HOME ./waf list | grep 'examples';

上传示例后,您可以连接控制台查看输出。控制台是什么取决于板的类型。在 Pixhawk 电路板上,控制台是 USB 接口。因此只需用您喜欢的串行程序连接到 USB 设备即可(波特率并不重要)。

例如,如果您安装了 mavproxy,就可以用它来连接 Linux 上的 Pixhawk:

mavproxy.py --设置 -- /设计/串行/-本我/USB-3D_Robotics_PX4_FMU_v2.x_0-if00

使用 -setup 选项可使 mavproxy 进入原始串行模式,而非处理后的 MAVLink 模式。这正是示例草图所需要的。

SITL 中的运行示例

某些草图也可以在 SITL 中运行。例如,运行协议解码器草图:

cd $ARDUPILOT_HOME # ArduPilot 资源库的顶层 ./waf configure --board sitl ./waf build --target examples/RCProtocolDecoder

要启动草图,请直接运行它:

./构建/坐标/例子/RCProtocolDecoder -M 四人 -C

了解示例草图代码

阅读示例草图代码(如 GPS_AUTO_test 代码),你会注意到一些起初看似奇怪的地方:

  • 它将 "hal "变量声明为引用

  • 代码相当粗糙,没有很好的注释

  • 设置()和循环()函数

哈尔参考资料

每个使用 AP_HAL 功能的文件都需要声明一个 hal 引用。这样就可以访问 AP_HAL::HAL 对象,该对象提供了对所有硬件特定功能的访问,包括向控制台打印信息、休眠以及与 I2C 和 SPI 总线对话等功能。

实际的 hal 变量埋藏在电路板专用的 AP_HAL_XXX 库中。每个文件中的引用只是提供了一种获取 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

现在就去 libaries/AP_HAL 目录中查看 HAL 可用功能的完整列表。

setup() 和 loop() 函数

您会发现每个草图都有一个 setup() 函数和 loop() 函数。电路板启动时会调用 setup() 函数。实际调用来自每个电路板的 HAL,因此 main() 函数被埋在 HAL 中,然后在特定电路板启动完成后调用 setup()。

setup() 函数只被调用一次,通常用于初始化程序库,也许还会打印一个 "你好 "的横幅,以显示程序正在启动。

setup() 完成后,(由 AP_HAL 中的主代码)将继续调用 loop() 函数。草图的主要工作通常是在 loop() 函数中完成的。

请注意,对于更复杂的电路板来说,这种 setup()/loop() 安排只是冰山一角。这可能会让人觉得 ArduPilot 是单线程的,但实际上下面还有很多事情要做,在有线程的电路板上(如 Pixhawk 和基于 Linux 的电路板),实际上会有很多实时线程启动。请参阅下文了解 ArduPilot 线程的部分。

AP_HAL_MAIN() 宏

你会发现每张草图的底部都会多出这样一行:

AP_HAL_MAIN();

这是一个 HAL 宏,可生成声明 C++ 主函数所需的代码,以及 HAL 的任何板级初始化代码。你很少需要关心它是如何工作的,但如果你好奇,可以在每个 HAL 的 AP_HAL_XXX 目录中查找 #define。它通常位于 AP_HAL_XXX_Main.h。

粗略的代码示例

您会发现,示例草图相当粗糙,注释也很糟糕。这正是你为代码做出贡献的机会!当你阅读示例草图并探索它们如何工作时,在代码中添加一些注释来解释应用程序接口,然后 提交拉取请求 以便他人从您的研究中受益。