I need help. I need to make a TCP socket client to read and write data to a socket server in the back end. The Java ME in the cRIO seems quite limited (I don’t have enough experience to back myself though), and I can’t figure out the default socket library. Java.net is absent so I cannot use the Java native functions.
The socket server is written in C++. It is meant to communicate data between the cRIO and my coprocessor, mostly, but to also allow me to tap into the datastream from a remote computer!
I have been searching in Google and CD for a while and I am only coming across solutions for Java SE and above!
Have a good day
Well, it doesn’t help right now… but in our Alpha and Beta testing of the new control system, the RoboRio uses full Java 8 SE. So, if you’re looking to create something that could possibly be used in the future, you can work with the full SE and get it working on the RoboRio when your team gets one.
That really doesn’t help too much, though. There is a chance that the Java SE might not be released in time. While that unfortunate chance is quite slim, I want to get started now. I want to get myself in a position in which I can calculate all the info I want on a separate computer with a lot of power, and send back the data to the cRIO. I guess that if I cannot get a network interface started, I might need to use a Raspberry Pi to convert these requests into a serial interface so I can use the serial I/O in the cRIO.
I would rather tend to avoid that method because it means that I will need to add another step in the data transfer, which will make the system prone to lag. With the level of AI I have planned, I need to do whatever I can to reduce lag! :(. Thanks for your answer, and I hope I can get this sorted out sometime soon!
Keep in mind that sending packets is a <sarcasm>bit</sarcasm> easier than writing AI scripts…
Also, remember the golden rule of efficiency, write the code first then determine if you have an issue. A thought-based AI will have no problem from the added delay by having a hardwired pie.
Also, I hope this is a stupid question but have you looked into NetworkTables?
I am using a library to make socket programming extremely easy. However, the easiest to implement protocol that it supports is TCP. Also, I want a constant bi-directional data transfer. I basically want to have some request system, where the cRIO can request some data from the coprocessor, and vice-versa. This would also allow me to use the same socket server to send data to a UI, etc.
UDP is my last choice. For some basic path-planning, I will need to ensure that all the requests complete in a structured order!
I guess that if I can implement NetworkTables on the coprocessor, that would make things extremely simple! However, I don’t think NetTables were built to be as portable as I want them to be!
Yes, but I can’t use that in FRC Java. It is in java.net, which is not present on the cRIO Java!
My main purpose of this thread is to find solutions that work in the current Java ME environment that the cRIOs run!
In time for what? While nothing is official until the season starts, Alpha teams have been using Java SE on the RoboRio successfully since last fall, and they didn’t make any changes when they moved into Beta… I’d say you’d be pretty safe moving forward with that path - just mock out the RoboRio part on another computer for now.
When I’m working on a project at work, I seldom have a production-equivalent environment I can do my development on. We set things up so we can do development where we need to do development, then deploy to system environments (scaled down production hardware), and eventually to something that is actually production equivalent and then production. Is it possible to adopt a similar approach here? It’ll save you a lot of headaches in the long run, as you can do development and some amount of testing without needing to monopolize time on the robot (or last years bot or practice bot or whatever). That time with the robot can probably be better spent with driver practice or build improvements.
You can definitely use streams on the Java cRIO. We have been using TCP for years on our robot.
Here is some code to help you get started
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.ServerSocketConnection;
import javax.microedition.io.StreamConnection;
import org.team2168.utils.Util;
private int port;
private String messageOut;
private volatile boolean clientConnected;
// A TCP Socket Connection
private ServerSocketConnection conn = null;
// TCP Socket Stream
private StreamConnection sc = null;
// Address Variable
private String addressIn = "socket://:" + port;
// Opens a socket to listen for incoming connections
try{
try {
conn = (ServerSocketConnection) Connector
.open(addressIn);
} catch (IOException e) {
e.printStackTrace();
}
// wait for a client to connect, this blocks until a connect
// is made
System.out.println("Listening on: "
+ conn.getLocalAddress() + " on port: "
+ conn.getLocalPort());
sc = conn.acceptAndOpen();
System.out.println("Client Connected");
} catch (IOException e) {
}
//To get the input stream
try {
InputStream is = null;
is = sc.openInputStream();
}catch (IOException x) {
x.printStackTrace();
}
//Example to get the output stream
OutputStream os = null;
try {
os = sc.openOutputStream();
while (true) {
//keep sending some message
messageOut = "Some Message";
buf = messageOut.getBytes("US_ASCII");
try {
os.write(buf);
} catch (IOException e) {
// e.printStackTrace();
System.out.println("Appears Client Closed "
+ "the Connection");
// close streams
os.close();
sc.close();
conn.close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
For 2015: Instead of using ServerSocketConnection and SocketConnection, just use ServerSocket and Socket classes to create TCP streams. It is much simpler to create a server in JavaSE
Here is an example for 2015 roboRio:
// A TCP Socket Connection for RoboRio
private ServerSocket listener = null;
// TCP Socket Stream connection
private Socket client = null;
private int port;
try {
listener = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
// wait for a client to connect, this blocks the current thread until a connect
// is made
System.out.println("Listening on port: " + listener.getLocalPort());
client = listener.accept();
System.out.println("Client Connected");
//For the input stream, try the following:
try {
DataInputStream is = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
//And for the outputstream try the following
try {
DataOutputStream os = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
I would say I could help, but our team has used a C++ server on the robot for as long as I can remember - the client on the display was in Java. There are some ‘tricks’ to getting performance enhancements, but if you’re going for full AI then you should focus on that specifically since that is by far the longest lead time to your goal.
I’d also recommend your robot be the server so you can control how often a client attempts re-connects at game time. You get 2-way comms if it’s a TCP socket.
UDP’s is unreliablity only results in lost messages when resource contention exists. I doubt there will be much of that in a well-designed version of a specialized appliance like a co-processor communicating with a robot controller.
To remove the possibility of lost or out-of-order messages, if the other solutions (already posted) hadn’t been available, you could implement a simple user-code handshake to ensure reliable, ordered delivery of UDP messages between the two processors.
I know that an efficient off-the-shelf TCP implementation is almost always the proper way to avoid reinventing the wheel; but one shouldn’t be scared of reinventing parts of it, if (and only if) necessary.
Ensuring reliable (in the connection-oriented communication sense) and ordered delivery isn’t all that hard, and wouldn’t add much overhead to an intra-robot comm link.
I am actually now going to use a web server. Since I am using dclib, a web server is a no-brainer and only requires like 5 lines of code! I think I’ll use the HttpClient in the cRIO from there! That should work just perfectly. It is the lag that I think of, though
The nice thing, however, is that I can now send POST messages and “inject” values into the serve table. If one table is not good enough, I can also spawn multiple servers with multiple ports too!
A web server could be interesting. We just got done experimenting with algorithmic JSON interpretation at work, and it is really promising for fast network comms.
I think I am just about done! I have even written a web interface, so the drivers can access the stored variables! It is really fast too and uses 0.7% CPU of one core on my i3 1.4GHz.
I have attached some screenshots. Also, I use a RAM cache (which is written in STL), so page loads are almost instant!
The code (as usual), is in my GitHub “Other” repositiory, here
The web server implementation was extremely simple. If you noticed, I am using DLib. DLib adds some of the simplest socket APIs you could imagine!
class web_server : public server_http
{
const std::string on_request(const incoming_things& incoming, outgoing_things& outgoing)
{
return "<html><body><h1>Hello World!</h1></body></html>";
}
};
I used this, plus a bunch of HTML + CSS + JavaScript skills to make this. I think I should make a new thread about this software because it is something that many teams might want for communications. The main problem is speed, but it has an extremely vast feature set!