图书馆草图示例¶
自己探索代码的第一步是使用库的示例草图。按照 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。
粗略的代码示例¶
您会发现,示例草图相当粗糙,注释也很糟糕。这正是你为代码做出贡献的机会!当你阅读示例草图并探索它们如何工作时,在代码中添加一些注释来解释应用程序接口,然后 提交拉取请求 以便他人从您的研究中受益。