0

I'm working on teleoperating remote-site robot via network.

I'm starting from scratch and I'm thinking about command packet to be sent to the robot.

I want to use simple protocol.

[LENGTH] [HEADER] [BODY]

LENGTH is bytes of [HEADER+BODY].

HEADER will include type of command, current mode etc...

BODY will include real data(goal position, velocity, torque etc..)

My question is this.

If I use this protocol, first I get the length of the packet and extract the data from the stream based on the length information.

But let's think about the case of "error in length data".

packet stream...

[10] [5Bytes] [10Bytes] | [15] [5Bytes] [10Bytes] | [15] [5Bytes] [10Bytes] ...

There is length error in first packet.

I think this error can break every packets following it.

I'll use UDP for command packet, and it doesn't guarantee that data will be received correctly.

I think this case is possible.

Is it really happens?

If it is, is there any solution for this?

2
  • I wouldn't want to be local site operator when the robot misses a UDP packet and decides to swing wildly towards my head because the arm isn't where you think it is anymore... Commented Dec 23, 2014 at 15:53
  • 1
    Packet delivery is not guaranteed in UDP, but I am pretty sure that lack of guarantee applies to whole packets only. When you do get a packet you can assume that it is complete. Commented Dec 23, 2014 at 18:55

4 Answers 4

1

If data loss, and esp. if byte loss is to be expected, you need to design your protocol to self-synchronise.

In a general case, you'd need to make an explicit provision.

In your case, you may circumvent this provision by careful observation of your data.

Rely on UDP

If your data is small enough (under 65,507 bytes per wiki), you can choose to send each command as a single UDP datagram.

You can also choose to packet several commands into a UDP datagram, but always so that a single command cannot span across UDP packet.

Then use sendto and recvfrom functions from socket API to send and receive datagrams with your chosen boundaries.

Rely on data itself

  • Datagram = [1-byte-len][header][data]
  • assume empty header is invalid
  • length byte must be [1..255]
  • assume there's often a datagrame [4][4-byte-header][no-data] in the stream
  • alternatively compile most frequent datagram length list (5,10,13,200)
  • validate data to detect when you are out of sync

Recovery scenario could be something like this:

  • processing [5][header-set-speed][255,173,14,0]
  • oh no, speed 255 doesn't make sense
  • assume synchronisation is lost
  • scan forward looking for likely start byte (e.g. 4)
  • found 4,100,23,34,56,4,78,... assume it's a datagram (4,100,23,34)
  • check datagram after this (4,78,...)
  • this and next datagrams check out, decide that synchronisation is recovered
Sign up to request clarification or add additional context in comments.

Comments

0

If you want to make your data exchange more or less reliable, you will need to implement schema for your packages and a validator. But the easiest way is to use one of the existing data formats like json, xml, bson and etc.

Comments

0

So from what I see you store all incoming data in a contiguous buffer, and the problem is losing the division point when length attribute is corrupted.

Now if you're dealing with traditional sockets you shouldn't need to worry of what is really the data link responsibility of having reliable data streams. Sockets return reliable data in chunks and you're free to add it to the buffer if need to.

But let's work with small chunks of 256 bytes for each packet.

As an example using sockets to receive data you will do something like this:

unsigned char* data = new unsigned char[256];

int size = recvfrom(sock, data, sizeof(buffer), ...);

This will fill data and size with the contents of the new packet. You can now check whether there is any data in data buffer using if(size > 0), and get packet data from the data buffer.

I would also recommend using TCP for sending simple commands that require reliability. Unless of course you continuously send commands with the most recent state. Writing your own UDP reliability system is great and allow for flexibility with either sending reliable or unreliable commands, but it's quite complex and so libraries like ENet exist.

Comments

0

There is length error in first packet.

Can't happen with UDP, unless you've disabled UDP checksums.

I think this error can break every packets following it.

True if it happens, but it can't.

I'll use UDP for command packet, and it doesn't guarantee that data will be received correctly.

Yes it does, unless you've disabled UDP checksums.

I think this case is possible.

No.

Is it really happens?

No.

If it is, is there any solution for this?

You don't need one.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.