And while I don’t know much about how servers work, it did pop into my mind that you could potentially make a real-time graph/dashboard for logging robot data (Something I have tried before but decided to put on hold).
Questions
What exactly is a Websocket? I know that it something to do with a link between two devices that allows for data transmission. After doing research on the internet I found that it’s like HTTP (Something I also don’t know much about) but it works in a way that you can send and get data from a server or device.
How do I send and receive data? I think I can connect to the Webserver by opening or connecting to it in python or another language but, I’m uncertain on the data sent between the device and my computer.
Is the output (On the robots side) the std::cout stream from my robot?
Do I have to use a different output “log” like printf()?
How do I send data to the robot? (I know this depends on the language however I was wondering if the robot needs a std::cin function or something)
What language would be suggested? I already know python and some C#/C++, and an intro to HTML. Is it advised for me to learn a language like R (I’m dealing with graphs and R seemed like a good statistical option) or JS (Seemed fairly easy to learn and very well documented).
If the output from the robot the cout stream is there a format where I can send multiple graphs / lines on those graphs in one line of text? This is what got me stuck last time because I would like to graph multiple things on my robot. Ideally the answer would be the smallest amount of characters possible so the cout stream can handle it at 10ms (the refresh rate of the motors and other sensors).
Feel free to correct any of my terminology and please be very clear on vocab because I don’t know any.
A Websocket is basically used for real-time data, like in a chat app, so if the data on the server is changed, then it will automatically give you the updated data instead of you having to periodically fetch it from the server. A popular Websocket is socket.io.
To send and receive data you can use the HTTP GET and POST methods respectively. In this case, you probably won’t need to use the GET method since you are just giving the server the data, and then that could display it on a website. I don’t understand the question of “is the output (on the robot’s side) the std::cout stream from my robot?” However, for the section question you probably don’t need to do that since the type of app you’re trying to make here is a dashboard, and you just want to send the data from the robot to the server, which can then handle displaying it on a website or some python program. I think you can just use the HTTP GET method to get the data from the server, and when the server receives that request you can give it whatever data you want, but you can’t exactly input it into a std::cin command.
For the robot you should probably use C++, and you could use something like curl for the GET and POST methods. On the website or however else you are displaying data, I would suggest using JavaScript along with something like Chart.js for displaying the data.
I don’t quite understand your last question, but I guess you could send the data in a CSV file type of format, and then use some type of character like "" to indicate different types of data.
I hope this helps, and feel free to ask other questions if you’re confused on what I’m talking about.
Thank you for your response. It’s very informative and I have a few questions.
Do you know of any python libraries that I could use?
I think it would be easiest for me to use python. (I’m trying not to use any kind of HTML or webpage because I don’t really know how to set one up)
How would I edit the server side code?
I know this is vague but it seems that most websockets have code running on the “server” side. I don’t know where or if I can edit the Vex server that is made by enabling the Webserver in VScode.
3.a Building off of the original question about the output from the Robot side (What I think the server side is), It sounds like I can grab data (GET) from the robot without sending an output from the code?
This is what I was talking about with Cout and Cin. The first time I tried to make a graph it was by intercepting the Cout stream (When you do an std::cout << INFO; or printf(“INFO”)) with a python program that was reading the USB port that the robot was on. With your response it sounds like I don’t need an output from the user program but can just ask the websocket for MotorX data and get it with out messing with any of my C++ code on the robot.
3.b Do you know if the GET and POST functions, would overload, or slow, the connection with the robot?
This is was worried about in Q4 of the original post. Sending robot data every 10 ms (Ideal speed because its the same as the update on motors) was too fast for the radio connection when plugged in to the controller (which needs to happen for testing on the field). I needed to find a way to transmit multiple graphs each with multiple lines that minimized the amount of characters used.
3.c Can I send a “Welcome” message to my client from the websocket server?
It would help if the problem above if I could send my Axis, Title, and other configuration data before I send a stream of numbers allowing for my code to interpret smaller sized data. The problem originally (the way I was doing it before) was that I couldn’t always assure that the python program was always running at the start of runtime of my code. Hence I couldn’t assure a configuration “welcome” message that is sent to my computer. Depending on your answer to 3a and 3b I may not need this Welcome message.
Python has a framework called Django which is meant for backend things, and for displaying the data I would suggest using something like Matplotlib. If you want to use something else other then Django for the backend then you can check out this Stack Overflow post.
Basically for the server side code you want to run it on localhost, which means that its running on your machine. When doing this you want to make sure it is the same port as the one you have set in VS Code, because it will be sending requests on that URL.
3a. Basically with web sockets the connection is two ways, so both sides can send and receive data. So instead of having to read the data out of the USB port from the python program you can simply just have the C++ program continuously use the HTTP POST method, and the python program can continuously process that in coming string of data.
3b. I don’t think this would be a big problem, and I would be kind of more concerned on the server side of things instead. The reason for that is, you would probably be sending a JSON object with something like 10 properties with 10 numbers, and that should probably be fine every 10 msecs. The thing is, the server-side code has to be able to take that data and render it quickly without freezing up, and this also probably won’t be a problem unless you are sending like an insane amount of data.
3c. I don’t quite understand why you would want to send an Axis, Title, and other configuration data, and I don’t know how that would help the code interpret smaller sized data. Though, you could probably still just use the HTTP POST method to the python program and it should be fine.
Something I would also suggest doing is maybe simply just writing out all of the data to a text file using the fstream library in C++, and then the python program could constantly read everything from there. You could also just store the data in the text file, and then once you are done printing out the data the python program can display the data because that might be a simpler way of creating the dashboard.
Thanks this mostly answers my questions but I have a few more.
If the Websocket is on my computer do I need to connect the robot?
Also the fstream doesn’t work because it sends data to the SD card and not the computer. As far as I am aware you can only use the cout stream to get an output.
I strongly recommend NodeJS for creating a WebSocket Client. Here is a template that might help you get started:
// Create an instance of the WebSocket class
const webSocket = new WebSocket("ws://127.0.0.1:7071/vexrobotics.vexcode/device");
// Define callback functions
function onOpen(event) {
// Code to execute once the connection has been established
// Send a message to the server
webSocket.send("Hello, world!");
}
function onMessage(event) {
// Code to execute every time a message has been received
console.log(event.data); // Prints the message to the std output
}
function onClose(event) {
// Code to execute once the connection has been closed
// Try to reconnect? End the program?
}
function onError() {
// Code to execute if an error occurred with the connection
}
// Register the event handlers
webSocket.addEventListener("open", onOpen);
webSocket.addEventListener("message", onMessage);
webSocket.addEventListener("close", onClose);
webSocket.addEventListener("error", onError);
/*
Explanation:
webSocket - instance of the WebSocket class
addEventListener - function that registers an event handler
"open" - name of the event to listen for
onOpen - function to execute when the event occurs
*/
// Close the connection at some point using:
// webSocket.close();
If you want to use Python, you should take a look at the websockets library.
You can easily change the port that the server is running on from the extension settings, but that’s about it.
Is it possible to change the code? Yes.
Is it unnecessary and not worth your time? Probably.
I believe that @Robot101 was providing information about how you can implement the HTTP protocol in general. The VEX robot brains do not have onboard wireless-transmission, and the radio is only capable of communicating with the controller and other radios using the proprietary VEX Communications Protocol.
The WebSocket Server is being hosted on whatever laptop or other device that the extension is running on. The messages being sent to the client reflect the output of the VEX Integrated Terminal. This means that the brain/controller must be connected to your device at all times if you want to receive data.
To send data, simply program your robot to write the diagnostic information to the output stream, preferably formatted so that you know what information is being sent (eg. Motor1Voltage: 6.12);
When programming with VEXcode ? sure you could have a Python program read the output of the V5 serial port, there’s nothing very different going on in PROS than VEXcode, both have pretty much the same capability.
If you want to look into reading the terminal with python there is this.
I’d suggest, if possible, using the websocket from the VScode extension. It seems, as of right now, to be easier and more streamlined than reading the serial output.