Read and write structures remotely

I am currently creating a robot to which some sensors are attached. The robot control unit is ARM Cortex-M3, all sensors are connected to it, and it is connected via Ethernet to the โ€œground stationโ€.

Now I want to read and write settings on the robot through a ground station. So I thought about introducing a "virtual register" on a robot that can be manipulated by a ground station.

It can consist of structures and look like this:

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

On the robot, the registers will be constantly filled with new values, and configuration settings are set by the ground station and applied by the robot.

The ground station and the robot will be written in C ++ so that both of them can use the same type of structure structure.

Question I have a question about how to encapsulate read / write operations in a protocol without writing a lot of metadata?

Let's say I want to read the robot.ir_sensors[2].dist . How can I access this register in my protocol?

I already thought about transmitting the relative offset in bytes (i.e. the relative position in the memory inside the structure), but I think that aligning and adding memory can cause problems, especially because the ground station runs on x86_64 architecture, and the robot runs on 32-bit ARM processor.

Thanks for any tips! :)

+4
source share
2 answers

I think the Google protocol buffers are a great tool for working with a session / presentation. In fact, the Google protocol buffers do not support the syntax I'm thinking of. So, I will modify this part of my answer to recommend XSD with Code Synthesis. Although it is mainly used with XML, it supports various levels of presentation, such as XDR, and may be more efficient than protocol buffers with lots of extra data. The generated code is also very good for work. XSD can be freely used with OpenSource software and even with commercial use with limited message structures.

I do not believe that you want to learn to read / write registers. You can prefix the message with enum , which stands for message, such as IR update , distance , accel , etc. These are groups of registers. Then the robot responds with a set of registers. All the registers that you have specified so far are sensors. should write be engine controls?

You want to think about what kind of control you want to perform and the type of telemetry you would like to receive. Then come up with a message structure and combine the information together. You can use sequence diagrams , and remote procedure APIs like SOA / SOAP , RPC , REST , etc. I do not mean this RPC framework directly, but concepts such as request/response and possibly a message that is sent periodically (telemetry) without any special requests. Thus, a telemetric request will be requested from the ground station at a certain interval, and then the robot will periodically respond to unsolicited data. You always need a message identifier ( enum above), unless your protocol is obsolete, which will prevent robustness reasons.

You have not described how the control system can work, or if you want to do it remotely. A description of what might lead to more ideas on the protocol. I believe that we are talking about 5,6,7 OSI layers. Enjoy.

+1
source

I am also going to propose Google protocol buffers.

In the simplest case, you can implement a single RobotState message as follows:

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

Then, when the robot receives the message, it will take new values โ€‹โ€‹from any optional field that is present. He will then reply with a message containing the current value of all fields.

Thus, it is very easy to implement field updates using the merge functionality of most protobuf versions. In addition, you can keep it very simple at startup because you only have one type of message, but if you need to expand it later, you can add subordinates.

It is true that protobuf does not support int8_t or int16_t . Just use int32_t .

+1
source

All Articles