2013-04-07 32 views
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處理器上。

感謝您的任何提示! :)

+3

我打算建議[Google協議緩衝](https://developers.google.com/protocol-buffers/),但您已經用這些標記了問題。是否有不使用它們的原因? – 2013-04-07 23:29:36

+0

嗨,乍一看它看起來並不像在ARM Cortex M3上運行,但我剛發現它有一個嵌入式版本! – sled 2013-04-07 23:38:44

+0

我已經在各種嵌入式設備(包括ARM)上成功運行GPB。這是我會做的,除非有一些困難。 – 2013-04-07 23:39:35

回答

1

我認爲 Google protocol buffers是一個很好的會話/表示層工具使用。 實際上,Google協議緩衝區不支持我想到的語法。因此,我將更改CodeGo.net,這部分我的答案建議XSD。雖然它主要與XML一起使用,但它支持不同的表示層,例如XDR,並且可能比具有大量可選數據的協議緩衝區更高效。生成代碼也很好用。 XSD可以免費使用OpenSource軟件,甚至可以使用有限的消息結構進行商業用途。我不相信你想隨機讀/寫寄存器組。您可以在消息前加上一個enum,表示一條消息,如IR update,distance,accel等。這些是寄存器組。然後機器人迴應寄存器組。目前爲止所有寄存器都是傳感器。 write必須是電機控制?

您想要考慮您想要執行的控制以及您希望接收的遙測類型。然後提出一個消息結構並將這些信息捆綁在一起。您可以使用sequence diagrams,以及遠程過程API,如SOA/SOAP,RPC,等。我並不是直接指這些RPC框架,而是指request/response等概念,也許這些概念只是定期發送(遙測)而沒有特定請求。因此,地球站會以某種間隔發出遙測請求,然後機器人會以未經請求的數據週期性地作出響應。你總是需要一個消息ID(上面的enum),除非你的協議是有狀態的,我會因爲健壯性原因而不鼓勵。

您尚未描述控制系統如何工作,或者您是否希望遠程執行此操作。描述這可能會導致對協議有更多的想法。我相信我們正在談論OSI的5,6,7層。玩的開心。

1

我也會建議Google協議緩衝區。

在最簡單的情況下,你可以實現一個消息RobotState這樣的:

 
message RobotState { 
    optional int32_t status = 1; 
    optional int32_t distance = 2; 
    optional int32_t accelX = 3; 
    ... 
} 

然後當機器人接收到消息,將採取新的值從任何可選字段,它是存在的。然後它將回復包含所有字段當前值的消息。

這樣,使用大多數protobuf實現的「合併消息」功能來實現字段更新非常容易。您也可以在開始時保持它非常簡單,因爲您只有一種消息類型,但如果您需要稍後擴展,則可以添加子消息。

protobuf確實不支持int8_tint16_t。改爲使用int32_t

+0

+1儘管在某些時候,我認爲可選的開銷會達到(也可能超過)使用* message id *。基本上八個選項應該與字節寬*消息ID *相同,如果我猜測如何正確使用google協議緩衝區實現可選項。 – 2013-04-08 15:43:21

+0

@artlessnoise如果您想將選項分組爲消息類型,請將它們作爲子消息。然後,可選的子消息的開銷與您的消息ID相同。 – jpa 2013-04-09 08:29:04

+0

對,我認爲無論採用哪種方式,都可以通過某種方式來構建消息,以減少開銷。重要的一點是消息結構**將減少開銷。 OP希望低開銷,但似乎要隨機*讀/寫*;我認爲這些目標有衝突,這是我答案的一部分。我想我有*協議緩衝區*不支持我所想的。這*是字面上的*真實的。我對他們不夠了解。我認爲可能有*子消息*是可能的,但我找不到有關* optional *或* submessages *編碼的文檔。 – 2013-04-09 13:36:50