(4)库示例概述

简介: (4)库示例概述

前言

自己探索代码的第一步是使用库的示例概述。遵循 arduino 传统,我们为大多数共享库提供了示例概述。一个 ‘sketch’ 就是一个主程序,编写为一个 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 # the top-level of an ArduPilot repository
./waf configure --board=Pixhawk1
./waf build --target examples/GPS_AUTO_test --upload

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

1. cd $ARDUPILOT_HOME
2. ./waf list | grep 'examples'

一旦你上传了这个例子,你就可以通过连接到控制台来查看输出。控制台是什么,取决于板子的类型。在 Pixhawk 板上,它是 USB 接口。所以只要用你喜欢的串行程序连接到 USB 设备(波特率并不重要)。

例如,如果你安装了 mavproxy,你可以这样做来连接到 Linux 上的 Pixhawk:

mavproxy.py --setup --master /dev/serial/by-id/usb-3D_Robotics_PX4_FMU_v2.x_0-if00

使用 --setup 选项可以使 mavproxy 进入原始串行模式,而不是经过处理的 MAVLink 模式。 这就是你对示例概述的需要。

1 在SITL中运行示例

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

cd $ARDUPILOT_HOME # the top-level of an ArduPilot repository
./waf configure --board sitl
./waf build --target examples/RCProtocolDecoder

要开始示例,请直接运行它:

./build/sitl/examples/RCProtocolDecoder -M quad -C

2 理解示例概述代码

当你在阅读示例概述代码(例如 GPS_AUTO_test 代码)时,你会注意到一些一开始可能看起来很奇怪的事情:

  • 它声明了一个‘hal’变量作为一个引用;
  • 这段代码很粗糙,没有很好的注释;
  • setup() 和 loop() 函数。

2.1 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;

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


2.2 setup()和loop()函数

你会注意到,每个示例都有一个 setup() 函数和 loop() 函数。当电路板启动时调用 setup() 函数。实际的调用来自每个板子的 HAL 内部,

所以 main() 函数被隐藏在 HAL 内部,然后在板子具体启动完成后调用 setup()。

setup() 函数只被调用一次,通常是初始化库,并且可能会打印一个“hello”标语以表明它正在启动。

setup() 完成后,loop() 函数被持续调用(由 AP_HAL 中的主代码调用)。示例的主要工作通常在loop() 函数中。

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

2.3 AP_HAL_MAIN()宏

你会注意到在每个示例的底部有这样额外的一行:

AP_HAL_MAIN();

这是一个 HAL 宏,产生必要的代码来声明一个 C++ 主函数,以及任何 HAL 的板级初始化代码。你几乎不必担心它的工作原理,但是如果你很好奇,可以在每个 HAL 的 AP_HAL_XXX 目录中查找 #define。它通常在 AP_HAL_XXX_Main.h 中。

2.4 粗略的示例代码

你会注意到,这些示例概述是相当粗糙的,而且注释不清。这是你为代码做出贡献的机会!当你在阅读示例概述并探索其工作原理时,给代码添加一些注释以解释 API,然后提交一个拉取请求(submit a pull request),这样其他人就可以从你的研究中受益。


相关文章
|
Python
python脚本基础示例
python脚本基础示例
69 1
|
JavaScript 前端开发
this如何使用
"this" 是 JavaScript 中的关键字,它通常用于引用当前执行上下文中的对象。
41 0
|
4月前
|
Web App开发 API C#
PuppeteerSharp库在C#中的应用案例
PuppeteerSharp库在C#中的应用案例
|
9月前
|
XML JSON 编解码
|
IDE 开发工具 C++
如何使用VS
如何使用VS
77 0
|
消息中间件 Java API
如何使用 ArrayPool
如果不停的 new 数组,可能会造成 GC 的压力,因此在 aspnetcore 中推荐使用 ArrayPool 来重用数组,本文将介绍如何使用 ArrayPool。
170 0
如何使用 ArrayPool
|
JSON 缓存 数据格式
由浅入深:Python 中如何实现自动导入缺失的库?
在写 Python 项目的时候,我们可能经常会遇到导入模块失败的错误:ImportError: No module named 'xxx' 或者 ModuleNotFoundError: No module named 'xxx' 。 导入失败问题,通常分为两种:一种是导入自己写的模块(即以 .py 为后缀的文件),另一种是导入三方库。
261 0
由浅入深:Python 中如何实现自动导入缺失的库?
|
机器学习/深度学习 算法 Linux
还在当调参侠?推荐这三个超参优化库【含示例代码】
在传统的算法建模过程中,影响算法性能的一个重要环节、也可能是最为耗时和无趣的一项工作就是算法的调参,即超参数优化(Hyper-parameter Optimization,HPO),因此很多算法工程师都会调侃的自称"调参侠"。近期在研究一些AutoML相关的论文和实现,而在AutoML中的一个核心组件就是HPO。借此机会,本文梳理总结Python中三种常见的可实现HPO的库,并提供一个简单的示例。
515 0
还在当调参侠?推荐这三个超参优化库【含示例代码】
|
搜索推荐 大数据 测试技术
|
Ubuntu 关系型数据库 MySQL
python api链接数据库
python api链接数据库
133 0