Log in

View Full Version : Transmitting data to the cRIO from the Driver's station via TCP/UDP


JohnGilb
22-08-2011, 20:10
In some other threads, I noticed programmers talking about sending data to the cRIO directly over TCP/UDP ports. Was this competition-legal? If so, what ports were accessible to us?

plnyyanks
22-08-2011, 21:11
More information was given about the open TCP/UDP ports available for use in Team Update 5 (http://uberbots.org/omni/media/files/Logomotion%20Documents/Team%20Updates/Team%20Update%205.pdf) (section 2.2.8)

Once plugged in to the Field Management System via the Ethernet cable provided, the ports that the
teams will be able to access on the playing field are as follows:
– TCP 1180: This port is typically used for camera data from the cRIO to the DS when the
camera is connected to port 2 on the cRIO. This port is bidirectional on the field.
– UDP 1130: Dashboard-to-Robot control data, directional
– UDP 1140: Robot-to-Dashboard status data, directional
– HTTP 80: Camera connected via switch on the robot, bidirectional
– HTTP 443: Camera connected via switch on the robot, bidirectional
January 25, 2011All these ports are open on the playing field, so a team can use them as they wish if they do not
employ them as outlined above (i.e. TCP 1180 can be used to pass data back and forth between the
robot and the DS if the team chooses not to use the camera on port 2).


We successfully got communication between robot and driverstation using these ports to work in LabVIEW, so if you need a hand with that, let me know and I'll dig it up.

JohnGilb
23-08-2011, 14:41
Thanks for the link! And indeed, if you have any sample code, I would definitely like to see it - out team is experimenting with this sort of thing in the offseason.

This certainly has the potential to be very useful - in the past, we've used the DS front panel as a way to get a lot of debugging information about the live robot, but this means we also have the capacity to send a wide variety of command/control signals without having to pipe it through USB or Analog/Digital pins =]

plnyyanks
23-08-2011, 15:33
No problem. Attached are two VIs, one for sending UDP packets, and one for receiving UDP packets. They show the basic concept of sending/receiving UDP packets (can also be substituted for TCP packets, the theory is the same - just substitute TCP VIs for UDP VIs). The network communication VIs can be found in the Data Communication -> Protocols -> UDP or TCP palate.

Now, there are two main ways you can do this. First you can "piggyback" off of the regular packets going between the robot and DS. To do that, in your robot code, open "Build Dashboard Data.vi" (in Team Code folder) and you can modify that cluster with your custom data (also make sure the "Dashboard Datatype.ctl" typedef is updated as well, you'll need that later). Then, in a custom dashboard project, update the big constant on the left side of the loop with the Dashboard Datatype (you can just copy&paste), and you can get your data there, after unflattening it from a string.

However, if you want to send data from the dashboard to the robot, the above method won't work very well. You have to use something related to the code I attached. In "Dashboard Main.vi" open up your connection outside the loop and read or write from it on the inside (you will want to put a pretty small timeout on that, maybe 50ms. This will keep your code executing quickly). Then, on the robot side, you can open a connection on the same port (make sure it's one of the ones open on the field) and do the opposite (read or write) of the dashboard.

Also, I should throw in an obligatory warning: do not use this to circumnavigate the standard way of driving robots (i.e. driverstation -> FMS -> robot). By this, I mean: only use this to send auxiliary data between the driverstation and robot. Do NOT attempt to try and get around the usual means of communication, only supplement them.

As always, if you have any questions or if I missed something, let me know, and I'll be glad to help.

Philipose
12-01-2012, 16:08
Hi I keep getting an error
"Error 56 occurred at UDP Read in Receiver.vi->Dashboard Main.vi"

The errors are coming from this subVI that you have provided. Do you know if the ports have changed in the new 2012 LabVIEW or if there is another incompatibility?

Thank You for your help in advance

plnyyanks
12-01-2012, 16:36
Error 56 (http://digital.ni.com/public.nsf/allkb/D90C4F99C1EF3F6A86256E4A0080A120) means that your code has timed out (i.e. the network hasn't given LabVIEW a response in an appropriate amount of time). Since the error is coming from the Read VI, that means that your code is waiting for a packet to be sent, but one isn't being sent. That makes your code time out.

Since that example wasn't really intended to be used on a robot, I did not specify a Timeout value (see the UDP Read Docs (http://zone.ni.com/reference/en-XX/help/371361H-01/lvcomm/udp_read/)), as the example was really only to demonstrate syntax. Now, that doesn't mean you can't use it on your robot, you'll just have to tweak a few things to get it to run in real time.

First, where in the code structure are you putting this VI (since you said the error happened in Read.vi, I'm assuming this is in the robot part of the code)? It should probably go in Timed Tasks.vi. There, you can make a while loop only for your UDP communication and put a relatively slow delay on it (~100 ms?). Then, you should put timeout values on your network VIs. The value is in milliseconds, so a value around 100 is probably good (this depends on how fast your loop runs).

If this code is on the driver station, then I'd just recommend using the dashboard communication that is already taking place to send data from robot->DS; it'l be much easier to work with (see my last post). But, if you're sending data from dashboard->robot, then this is one of the better options.

If you keep getting errors, you can always unbundle the error out cluster and check if it's a timeout error (the code part of the cluster is 56) and clear that specific error. I can elaborate on that more, if you need.

SuperS_5
12-01-2012, 20:33
i have not checked the latest cRIO image but last years version had a problem with an unchecked buffer. the tcpip would crash the communications with the robot if to many directed packets arrived at the robot but were not retrieved from the buffer. To avoid this, make sure that the robot code us running before you start sending data to it, and limit you traffic to the robot. I used this method to control the robot via an Android and IOS devices in the off season.

NeatNit
28-01-2012, 22:00
Would it be legal to do vision processing in the Dashboard and sending the results to the cRIO? If so it seems like the easiest solution. The Dashboard already receives a camera image, and its computation power is hardly used while driving the robot. I'm just not sure about the rules (couldn't see any that disallow it but may have missed it or didn't look well enough).

Just for convenience, here's the port list from this year's manual:
2.2.9 The Player Stations
One Player Station is located between the Inbound Station and Corral. The remaining two Player Stations are located on the opposite side of the Corral. The Player Station on the end of the Alliance Wall is 51 in. wide, while the other two Player Stations are 72 in. wide. All three Player Stations have the components detailed below.

Attached to the Alliance Wall in each Player Station is an aluminum shelf to support the Operator Consoles for the FRC team in that Player Station. The support shelf measures at least 48 in. wide by 12 in. deep. There is a 3 ft long by 2 in. wide strip of Velcro tape (“loop” side) along the center of the support shelf that may be used to secure the Operator Consoles to the shelf. Each setup location includes a competition cable (to provide Ethernet connectivity) that attaches to the Ethernet Port of the Operator Console. The cable provides communications with the Robot.

Each Player Station also includes a power adaptor cable that may be used to power the Classmate laptops that were provided to teams in the Kit of Parts starting in 2010. Emergency Stop (E-Stop) buttons for each Robot are located on the left side of each Player Station shelf. Arena components (including team number displays, competition arena hardware, alliance lights, control hardware cabinets and clock displays) are also located above the Player Stations and below the shelf.

Once plugged in to the Field Management System via the Ethernet cable provided, the ports that the teams will be able to access on the playing field are as follows:
– TCP 1180: This port is typically used for camera data from the cRIO to the DS when the camera is connected to port 2 on the cRIO. This port is bidirectional on the field.
– TCP 1735: SmartDashboard, bidirectional
– UDP 1130: Dashboard-to-Robot control data, directional
– UDP 1140: Robot-to-Dashboard status data, directional
– HTTP 80: Camera connected via switch on the robot, bidirectional
– HTTP 443: Camera connected via switch on the robot, bidirectional

All these ports are open on the playing field, so a team can use them as they wish if they do not employ them as outlined above (i.e. TCP 1180 can be used to pass data back and forth between the robot and the DS if the team chooses not to use the camera on port 2).




So yeah, questions:
1. Is port 1130 used in the default code? Is it used in any optional SubVIs that make things easier? (I don't really need it to be easier)
2. Would it be legal to do vision processing in the Dashboard and sending the results to the cRIO? (If it's legal, is it legal during Autonomous/Hybrid as well?)

Pirate programe
06-02-2012, 17:30
We're trying something similar to the OP here: We want to have the Dashboard sent to the robot using UDP. We're simply opening a socket on UDP port 1130, using the Flatten to String function to turn the image into a string for transmission, then sending to the cRIO w/ the UDP Read function. However, we're getting the following error:

Error 113 occurred at UDP Write in Dashboard Main.vi

Possible reason(s):

LabVIEW: A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram was smaller than the datagram itself.

We haven't actually set any sort of buffer, so this is sort of confusing. If the datagram is actually too large to be sent, then we'd need some way to compress the data.

EDIT: Turns out the Clear Simple Errors VI was missing. This issue's cleared up.

Now, though, the data doesn't seem to be getting to the cRIO. We're reading the UDP socket from the Periodic Tasks VI, and the Emptry String function is reading True, which says to me that there isn't any information coming through the UDP connection.

plnyyanks
06-02-2012, 17:56
We haven't actually set any sort of buffer, so this is sort of confusing. If the datagram is actually too large to be sent, then we'd need some way to compress the data.

The buffers are there. Look at the input to UDP Read; you can set a number of bytes to read. If you're getting this error, why can't you just send all your data using more than one packet? You can split up all your information and send different parts of it on different iterations (this is actually how the robot sends large amounts of data to the dashboard).

Pirate programe
06-02-2012, 18:03
See the edit.

Greg McKaskle
06-02-2012, 19:52
UDP is a very basic communications protocol, quite good for sending small amounts of data in a repeating fashion. If you find yourself with more data than will fit in UDP ( about 1500 bytes is typical ), I'd suggest using TCP.

TCP will automatically break a big packet into smaller ones, and reassemble on the read end. It ignores duplicates, checks for missing elements and corrupted elements, and puts sub packets back in order if they happen to arrive out of order. There are other difference too, but the camera and other HTTP sessions are based on TCP.

The error you received was indicating that the buffer was bigger than the UDP limit. When the issue looked cleared up, it was just that you were discarding the error.

As I pointed out in the other thread, there is no reason to send an image. The dashboard already displays it. Why send it again?

Greg McKaskle

Pirate programe
07-02-2012, 17:09
How big is the UDP buffer? Because all that I'm sending is the Target Info array from the vision code flattened to a string...

Greg McKaskle
07-02-2012, 20:40
I believe the UDP limit is somewhat dependent on the devices being used, but in this instance, I think 1500 bytes or so.

Greg McKaskle

Pirate programe
08-02-2012, 17:24
The TCP code in the screenshot is giving me the following error:

Error 56 in TCP Write in Dashboard Main.Vi

Possible reason(s); The network operation exceeded the user specified or system time limit.

I can only assume this means it's timing out, but why would it do that? It seems as if all of the parts are in the right place.

Bendito
28-02-2012, 00:11
This thread has been quite helpful. I am still somewhat stuck with an issue on the cRIO crashing when I send UDP to it. I suspect it has something to do with the buffers, but if anyone has helpful advice, I'm open to it!

apalrd
28-02-2012, 08:14
A couple of TCP and UDP tips and comments:

-A UDP packet is designed to fit in one Ethernet frame, limiting it to 1500bytes minus UDP headers. I believe a UDP header is 8 bytes, but don't quote me on that

-TCP is designed to send streams of bytes instead of packetized data. The disadvantage to this is that the sending application must explicitly manage the send buffer and force TCP to send it all of the bytes, and the receiving application must manage packet starts/ends.

-TCP is also a reliable medium, with error checking and retransmission. This is usually a bad thing if you care more about getting the data fast than getting all of it (if you miss a targeting packet, you will get another one in about 50ms, so you just ignore it).

-UDP is a better choice for this application due to the speed and packet-oriented nature.


-The UDP listener should have errors trapped and a timeout set to a fairly low number (I use 1000ms) - I use trapped errors as a source of determining if I actually should unbundle the packet and use it

-The UDP listener should exist in its own thread (While loop) throttled by nothing other than itself - There should be no waits. The UDP listener will block for new packets, and if you are behind in receiving packets then it's a bad thing.

-Send the smallest packets possible - Do all target filtering and multiple target analysis (stuff that works with arrays of targets) on the laptop, and send a single target coordinate to the robot over UDP - This keeps the packet size under the limit and non-variable.

Greg McKaskle
28-02-2012, 08:21
I didn't run your code yet, but looking at the screenshots, it does look like you are only reading the udp data five times a second, pretty slow. But you shouldn't crash the cRIO doing that. What sort of crash is it?

Greg McKaskle

Doug Norman
28-02-2012, 15:39
This thread has been quite helpful. I am still somewhat stuck with an issue on the cRIO crashing when I send UDP to it. I suspect it has something to do with the buffers, but if anyone has helpful advice, I'm open to it!

When you say crash - exactly what happens? If you can reproduce a crash with a simplified program, please contact National Instruments via our FRC forum (https://decibel.ni.com/content/community/first/frc?view=discussions). We can have application engineers look into it.

marccenter
28-02-2012, 20:55
CD,
Man, most of this stuff is over my head. Is there a simple example somewhere to show how to display a PWM channel, Joystick Input, or global variable on the Dashboard?

Mark McLeod
28-02-2012, 21:05
There is an example in the Tutorials that come with LabVIEW.
From the Getting Started window, look at Tutorials -> Tutorial 7 - Integrating Examples into Robot Code
Then page down to Part 2 and it gives a step-by-step using a gyro output as an example.

Bendito
28-02-2012, 22:57
The UDP listener should have errors trapped and a timeout set to a fairly low number (I use 1000ms) - I use trapped errors as a source of determining if I actually should unbundle the packet and use it

-The UDP listener should exist in its own thread (While loop) throttled by nothing other than itself - There should be no waits. The UDP listener will block for new packets, and if you are behind in receiving packets then it's a bad thing.
Thank you, I fixed this, and created a much more simplified communication system. It actually works flawlessly now (even through repeated power ups/downs between robot and driverstation) I have some screenshots of it included.

When you say crash - exactly what happens? If you can reproduce a crash with a simplified program, please contact National Instruments via our FRC forum. We can have application engineers look into it.

The crash that occurs was happening whenever I was trying to debug the robot through running the robot program while still in labview with probes set up. It seems that when the driverstation tries to connect with the robot, it boots off labview's connection with the cRIO. A "Connection with the cRIO was lost" would appear, and there would be no way to put more code on without closing the driverstation. This was causing me to think it was crashing, and causing a lot of hair pulling in the debugging process, but was eventually figured out.

marccenter
29-02-2012, 06:36
Thanks Mark for pointing me to the right section. One observation and one question remains.

Observation - It may be implied or understood, however, in order to have the Dashboard Main.vi become updated with the changes shown in the tutorial I found myself creating my own dashboard project on the classmate and then manually moving the 3 files created by the dashboard project (C:\Users\developer\documents\Labview Data\builds|FRC Dashboard Project|FRC PC Dashboard) to the C:\Program Files\FRCDashboard subdirectory in order for the classmate to find the new Dashboard Main.vi (did I rename the two original files in the directory late last night before copying?).

Question: I am trying to extend the example to multiple pieces of data rather than just one by trying to use the bundle function in the Dashboard Main.vi function but it doesn't seem to take it. I was able to bundle, flatten to string and input this to the Driver station Set User Data HI function inside my robot project code. Should I be able to unpack this in my new dashboard project or is the Data Hi function simplistic?

Alan Anderson
29-02-2012, 09:01
I was able to bundle, flatten to string and input this to the Driver station Set User Data HI function inside my robot project code. Should I be able to unpack this in my new dashboard project or is the Data Hi function simplistic?

You can certainly do what you are suggesting. When you do the "unflatten" operation in the Dashboard, you need to show it an example of the data type you want it to create. That means you need either a bundle constant that matches the arrangement of the bundle you created in the robot project, or a typedef that you can share between the robot and dashboard projects so the robot code can do a bundle by name instead of just bundling raw data.

Mark McLeod
29-02-2012, 09:05
Copying the Dashboard files to FRC Dashboard works, you also have the options of changing the build destination to FRC Dashboard so it always gets put there when you build, or changing the Driver Station .ini file to point to your dashboard location.

Here is an example of some quick Dashboard diagnostics looked at from both the robot and the PC side of things. This is slapped together, so take it as development code. The elements are in the order they were added to the cluster on the robot side. I recreate an indicator "358 Custom data" whenever I add or remove elements, then copy that to the Dashboard side to define the order/types of elements in the cluster.
In the final robot I'd create a TypeDef to define each data element. That gives everything a name making it easier to digest and clearer to work with.

marccenter
29-02-2012, 19:34
Alan and Mark,
Alan - Thanks for commenting. I understand what you are saying, just need to fumble my way through Labview to make it work.
Mark - Jackpot! That's exactly the example I was looking to find. Now, time to fight with Labview again to make it work. Is there a way to bookmark/highlight that example in our documentation - great job!
BTW, can you point to an example about the 358 Custom Data vi object? This is a new function for me to work with. Mine is not shaded pink yet.

plnyyanks
29-02-2012, 19:53
BTW, can you point to an example about the 358 Custom Data vi object? This is a new function for me to work with. Mine is not shaded pink yet.

When you have a cluster (like you would use for custom dashboard data), you can right click on it and choose Create->Indicator. You can then copy/paste this indicator to other VIs (like your dashboard project) and use it there (you can change it back to a constant, if you need). It's not really a function, per se, but it's a way to make sure datatypes stay synced between projects.

marccenter
29-02-2012, 20:55
Phil Lopreiato,
THanks for the tip - very helpful for folks like me struggling their way through Labview- especially the copy and paste of the Indicator.

marccenter
29-02-2012, 23:51
Mark's 358 Custom Data Indicator looks different than mine -- what did he do differently? I can't seem to select the one in the menu. I selected an indicator but his has bubbles?? Does he have some kind of "Mr Bubbles special arrangement"?

Mark McLeod
01-03-2012, 20:56
Right-click on the indicator and un-check "View as icon"

Or in my case, I un-checked the Tools->Options->Block Diagrams->General->Place front panel terminals as icons.

PSHRobotics
02-03-2012, 18:51
So we tried doing this same thing with out dashboard and robot. Specifically sending three enum values from the dashboard to the robot. We got this working when we were running live on the robot through labview on a development computer. We would get one of the "The loop containing the RobotDrive code is running to slowly" error every once in a while but the code would function almost perfectly.
Once we deployed the code to the robot ("set as startup" after building), however, we started to get "Watchdog not fed" errors that would stop the code. Once we pulled the UDP receive stuff from the code on the robot, everything started working right. We decided to use the digitial inputs on the driverstation instead, but I would like to figure out what we did wrong in the old code. Does anyone have any ideas why this would have happened?

Greg McKaskle
03-03-2012, 08:16
I glanced through the forum posts, but couldn't find how you are doing the UDP. Where was it running? Make sure you build and Run as Startup so that you are running the new code. The behavior shouldn't change between the debug-run and the build-run.

If you don't figure it out, post the code or pictures of it.

Greg McKaskle

Pirate programe
05-03-2012, 16:01
Has anyone managed to solve the problem of the UDP transmission interfering with the normal Driver Station communication?

Alan Anderson
05-03-2012, 16:53
What problem?

Pirate programe
05-03-2012, 17:01
See, every time we've tried to send information to the robot using UDP, it's hindered the regular communication: The robot will stall during Teleop and Autonomous, the communications light on the Driver station will turn on and off, and occasionally, we'll lose the connection entirely.

Bendito
05-03-2012, 17:50
See, every time we've tried to send information to the robot using UDP, it's hindered the regular communication: The robot will stall during Teleop and Autonomous, the communications light on the Driver station will turn on and off, and occasionally, we'll lose the connection entirely.

Are you sending data too fast? The way I got it working, I had a loop wait timer in the transmission loop, along with no wait timer on the recieving loop, (but having a good timeout value on the recieving loop.) I posted some screenshots of working UDP sending and recieving for the robot a few posts back.

Send (http://www.chiefdelphi.com/forums/attachment.php?attachmentid=12158&d=1330487818)
Receive (http://www.chiefdelphi.com/forums/attachment.php?attachmentid=12157&d=1330487732)

PSHRobotics
11-03-2012, 14:07
I glanced through the forum posts, but couldn't find how you are doing the UDP. Where was it running? Make sure you build and Run as Startup so that you are running the new code. The behavior shouldn't change between the debug-run and the build-run.

If you don't figure it out, post the code or pictures of it.

Greg McKaskle

Thanks for taking the time to respond. I have added pictures because I am not really sure what we are doing wrong. The robot receive code is in the periodic tasks vi and the dashboard send is in the dashboard main vi.
Right now the image processing is in the same loop as the udp send, but we did separate it from this loop to check if that was slowing down the code, but there was no difference in effect.

Again, the problem is that when we "run as startup" we get enough watchdog errors to make the robot essentially undrivable.


Edit: forgot to note the "larger" sized photo is the send and the smaller is the recieve

Mark McLeod
11-03-2012, 14:13
You're missing a Wait in the second block diagram.
That will suck all the life out of your CPU.

Alan Anderson
11-03-2012, 16:38
You're missing a Wait in the second block diagram.
That will suck all the life out of your CPU.

I haven't memorized the UDP function icons, so I might be reading it backwards, but I think that second diagram is the receive processing. As such, it will only run when a new UDP packet is received (or until the UDP receive timeout occurs, which is 25 seconds by default). It doesn't need a Wait inside the loop, and adding one can actually cause some undesired effects if packets arrive faster than the loop time.

PSHRobotics
11-03-2012, 16:54
Well we did have a wait in there (30 ms), but while using the debug-run we started to get watchdog errors which had us loose control for a few moments about every 10 seconds. Those errors were more or less random and we had times where they would not happen for about a minute and then they would continuously happen. After taking out that wait we stopped seeing that problem and actually thought we had everything fixed - until we did a "run as startup".

Alex698
13-03-2012, 17:00
Well we did have a wait in there (30 ms), but while using the debug-run we started to get watchdog errors which had us loose control for a few moments about every 10 seconds. Those errors were more or less random and we had times where they would not happen for about a minute and then they would continuously happen. After taking out that wait we stopped seeing that problem and actually thought we had everything fixed - until we did a "run as startup".
I was having the exact same problem and it was driving me nuts, however I think I have resolved the issue. I stopped having driver station interference problems when I used a String-to-IP function fed into the open UDP VI into the net address input. It should match your team IP: 10.te.am.02. Also you should set the UDP Write VI net address to your team IP.

PSHRobotics
13-03-2012, 18:17
I was having the exact same problem and it was driving me nuts, however I think I have resolved the issue. I stopped having driver station interference problems when I used a String-to-IP function fed into the open UDP VI into the net address input. It should match your team IP: 10.te.am.02. Also you should set the UDP Write VI net address to your team IP.
That is a good catch, and if we get a chance we will try that, thanks!
My only concern about that is that we were able to send data using our code to the robot so the actual communication was not having problems, and because the open is outside of all loops I don't see how it could have caused the communication indeterminacy/watchdog errors when the communication was working.

We did have the UDP Write VI using our team IP (which we got using the global variable for Robot IP).

rwood359
15-03-2012, 18:00
Are you sending data too fast? The way I got it working, I had a loop wait timer in the transmission loop, along with no wait timer on the recieving loop, (but having a good timeout value on the recieving loop.) I posted some screenshots of working UDP sending and recieving for the robot a few posts back.



Thanks for posting these routines. We have used them with slight mods and have our image processing working pretty well.

We are running a modified version of the supplied Rectangle routine. Right now it is running as an independent program. We have the Drivers Station, Dashboard, and our image processing running. Is there a reason or rule that requires that the image processing be integrated into Dashboard? Will FMS know or care that it is a standalone program?

RufflesRidge
15-03-2012, 18:15
Thanks for posting these routines. We have used them with slight mods and have our image processing working pretty well.

We are running a modified version of the supplied Rectangle routine. Right now it is running as an independent program. We have the Drivers Station, Dashboard, and our image processing running. Is there a reason or rule that requires that the image processing be integrated into Dashboard? Will FMS know or care that it is a standalone program?

UDP traffic is UDP traffic. As long as it's on the right port none of the networking hardware will know what program it came from. I also don't see any rules that prevent you from running whatever software you want on your DS PC as long as it is in addition to and not instead of the DS software (though I would personally recommend against Minesweeper, Solitaire or Pinball)

Mark McLeod
15-03-2012, 22:53
The only required program is the Driver Station app.
The Dashboard is entirely optional as well as any other programs, such as the Kinect Server. I've run wordpad so I could take notes.