facontidavide / PlotJuggler

The Time Series Visualization Tool that you deserve.
https://www.plotjuggler.io
Mozilla Public License 2.0
4.36k stars 610 forks source link

DataStream plugins: Serial port #178

Closed Guillaumebeuzeboc closed 5 years ago

Guillaumebeuzeboc commented 5 years ago

Hello,

For a custom application, I needed to use PlotJuggler with data coming from Serial port. I wrote my own plugin (This is just a first version). But I was wondering if someone would be interrested in me contributing this back to the original PlotJuggler. Althougt this is a first version I also have a bit of time if some changes are necessary in order to integrate it. I used DataStreamWebSocket as an example. If someone wants to have a look: https://github.com/Guillaumebeuzeboc/PlotJuggler/commit/bc53cdb10c676d88c3043a7acfa5ad0095de7aa4

facontidavide commented 5 years ago

The big problem with this is not the transport layer but the protocol.

You might want to take a look to this:

https://hackaday.io/project/5334-serialplot-realtime-plotting-software/discussion-96229

Guillaumebeuzeboc commented 5 years ago

Thanks for the link, I didn't know about this soft. Although I found out that it was not covering all my use cases (operation on data etc are missing).

I am not getting what you mean with "the problem is the protocol". Would it really be an issue to add options for the protocol (like stop bits, flow control, parity, etc)? In my case, I just have to pick the port and the baud rate (I wanted something simple since most of the time everybody is more or less using the same protocol ie: flowcontrol: none, Databits:8, parity:8, stopbits: 1)

facontidavide commented 5 years ago

What I mean is that I get a stream of bytes from the serial, and I need to convert that into timeseries with a name. In your code there is your own protocol, but apparently you embed the name of the data into each message. This us a huge amount of bandwidth.

Guillaumebeuzeboc commented 5 years ago

oh yes, I didn't think about bandwidth, I just copied the protocol I saw in the plugin DataStreamWebSocket thinking it was somehow a "standard" for PlotJuggler. I just had a look to the zmq plugin and it's a different "protocol". So yes I guess it would be too specific and probably too bandwidth consuming for a general usage

facontidavide commented 5 years ago

There is no official protocol for Plotjuggler, For this reason it is hard to define "official" plugins.

A ideal Serial plugin would read a protocol from file (XML?) and receive only numeric data from the serial line

Guillaumebeuzeboc commented 5 years ago

I see, but in my case, I am using PlotJuggler to debug and display on the fly data. So in my soft, I just have to write write_serial("my_data", data). Writing an XML or anything else every time I want to plot another data would be a pain I think (In my case at least)

ubaldot commented 6 months ago

Hello guys, I opened a discussion on the Discussion section and then I bumped here. I also use seriaplot but given its limitations, I was looking into alternatives and I discovered jugglerplot.

I agree that the problem with the serial port is that everyone can define his own frame, and the idea of @facontidavide of defining a protocols in a e.g. xml file could be interesting.

However, perhaps a lower hanging solution that I believe could cover a huge amount of use-cases, would be the following: a serial message could trivially be a stream of lists of floats (in binary or ascii format that can be rearranged on the jugglerplot side.

For example, say that you have three signals A, B and C, then at every sampling instant you have messages coming from the serial in the form of [2.1, -5.9, 0.6], [3.6, 1.6, -4,7], […, …, …] Then, from jugglerplot side you define the signal names and reconstruct the timeseries as:

A = 2.1, 3.6, … B = -5.9, 1.6, … C = 0.6, -4.7, …

That is, if m is list of floats received from the serial port, then for every received m you associate A = m[0], B = m[1] and C = m[2]. It should be clear from a hypothetical plugin how to use it. I also think this trivial protocol covers an incredible amount of use-cases. What do you think?

Disclaimer: I am just providing an input, I absolutely have no skills for writing code for implementing it.

simoneruffini commented 5 months ago

I follow your idea with a simpler approach: at it's core a serial stream can be viewed as a csv file that is continuosly updated if you format it like that.

There is no official protocol for Plotjuggler, For this reason it is hard to define "official" plugins.

A ideal Serial plugin would read a protocol from file (XML?) and receive only numeric data from the serial line

So following this idea of the XML file, but doing something simpler, is it possibile to make plotjuggler read a csv file that continuously updates? You could define the first row of the csv yourself like for example:

# serial_stream.csv file
tick, pos_x,pos_y,acc_x,acc_y;

And then from the operative system just append the serial data that has to follow the same syntax of the csv header:

tail -f /dev/ttyACM0 >> serial_stream.csv

Then plotjuggler can read such stream

ubaldot commented 5 months ago

...or one could write a simple python script that encapsulate the serial port transmitted values into the payload of an existing communication protocol such as UDP.

simoneruffini commented 5 months ago

...or one could write a simple python script that encapsulate the serial port transmitted values into the payload of an existing communication protocol such as UDP.

Yes, doable but it is definitely more simple to have the feature in the same project for portability purposes (not all the people that use plotjuggler are tech savvy/developers). Still for now I will use this approach. Do you have some examples of such code?

Bartimaeus- commented 5 months ago

...or one could write a simple python script that encapsulate the serial port transmitted values into the payload of an existing communication protocol such as UDP.

Yes, doable but it is definitely more simple to have the feature in the same project for portability purposes (not all the people that use plotjuggler are tech savvy/developers). Still for now I will use this approach. Do you have some examples of such code?

There's an example UDP streaming script here: https://docs.ros.org/en/noetic/api/plotjuggler/html/udp__client_8py_source.html

I've used this to stream data from a complex Python application that was communicating with over a dozen different hardware devices and the streaming to Plotjuggler with this method worked on the first try.

ubaldot commented 5 months ago

There's an example UDP streaming script here: https://docs.ros.org/en/noetic/api/plotjuggler/html/udp__client_8py_source.html

I've used this to stream data from a complex Python application that was communicating with over a dozen different hardware devices and the streaming to Plotjuggler with this method worked on the first try.

Awesome! That is mutatis-mutandis exactly what I meant!