4

我目前正在构建一个带有一些传感器的机器人。机器人上的控制单元是 ARM Cortex-M3,所有传感器都连接在上面,并通过以太网连接到“地面站”。

现在我想通过地面站读取和写入机器人上的设置。因此我考虑在机器人上实现一个可以被地面站操纵的“虚拟寄存器”。

它可以由结构组成,如下所示:

// accelerometer register
struct accel_reg {
  // accelerations
  int32_t accelX;
  int32_t accelY;
  int32_t accelZ;
};

// infrared distance sensor register 
struct ir_reg {
  uint16_t  dist; // distance
};

// robot's register table
struct {
  uint8_t     status;         // current state
  uint32_t    faultFlags;     // some fault flags
  accel_reg   accelerometer;  // accelerometer register
  ir_reg      ir_sensors[4];  // 4 IR sensors connected
} robot;

// usage example:

robot.accelerometer.accelX = -981;
robot.ir_sensors[1].dist = 1024;

在机器人上,寄存器将不断填充新值,并且配置设置由地面站设置并由机器人应用。

地面站和机器人将用 C++ 编写,因此它们都可以使用相同的结构数据类型。

我现在的问题是如何在不写入大量元数据的情况下将读/写操作封装在协议中?

假设我想读取寄存器robot.ir_sensors[2].dist。我将如何在我的协议中处理这个寄存器?

我已经考虑过以字节为单位传输相对偏移量(即结构内内存中的相对位置),但我认为内存对齐和填充可能会导致问题,特别是因为地面站运行在 x86_64 架构上,而机器人运行在 32-位 ARM 处理器。

感谢您的任何提示!:)

4

2 回答 2

1

我认为Google 协议缓冲区是一个出色的会话/表示层工具。 实际上,谷歌协议缓冲区不支持我正在考虑的语法。因此,我将更改这部分答案以通过代码合成推荐XSD 。尽管它主要与 XML 一起使用,但它支持不同的表示层,例如XDR,并且可能比具有大量可选数据的协议缓冲区更有效。生成代码也非常好用。 XSD可以免费与开源软件一起使用,甚至可以在消息结构有限的情况下用于商业用途。

我不相信你想随机读/写寄存器集。enum您可以在消息前加上表示消息的 an 前缀,例如IR updatedistanceaccel等。这些是寄存器组。然后机器人以寄存器组响应。到目前为止,您提供的所有寄存器都是传感器。那些write必须是电机控制?

您要考虑要执行的控制以及要接收的遥测类型。然后提出一个消息结构并将信息捆绑在一起。您可以使用SOA/SOAPRPCRESTsequence diagrams等远程过程 API 。我不是直接指这些 RPC 框架,而是指诸如消息之类的概念,它们可能只是在没有特定请求的情况下定期(遥测)发送。因此,地面站会以某种间隔发出遥测请求,然后机器人会定期用未经请求的数据做出响应。您总是需要一个消息 ID (request/responseenum以上),除非您的协议将是有状态的,出于稳健性原因,我不鼓励这样做。

您还没有描述控制系统如何工作,或者您是否希望远程执行此操作。描述这可能会导致对协议的更多想法。我相信我们正在谈论OSI的第 5、6、7 层。玩得开心。

于 2013-04-08T01:24:17.160 回答
1

我还将建议使用 Google Protocol Buffers。

在最简单的情况下,您可以像这样实现一条消息RobotState

消息机器人状态 {
   可选 int32_t 状态 = 1;
   可选 int32_t 距离 = 2;
   可选 int32_t accelX = 3;
   ...
}

然后,当机器人收到消息时,它将从存在的任何可选字段中获取新值。然后它将回复一条包含所有字段当前值的消息。

这样,使用大多数 protobuf 实现的“合并消息”功能来实现字段更新非常容易。您也可以在开始时保持非常简单,因为您只有一种消息类型,但如果您以后需要扩展,您可以添加子消息。

确实 protobuf 不支持int8_tor int16_t。改用就好int32_t了。

于 2013-04-08T07:43:51.957 回答