Which communication protocol is best?

I’m programming a practice bot to be controlled with OSC on the side. I need help finding the best communication protocol for transferring simple numeric values from my laptop to the bot to drive it. It is just a 6 wheeled, single joystick controlled bot. The type of communication protocol has to be fast and reliable. Also, along with the communication methods, how can I send them from my laptop with this method? I wanted to go with Processing, and communicate the values via serial, but that would require a null modem cord, and I want this to be “as wireless as possible” I have the drive code already done in Wind River, but I just don’t know how what method is superior, and how to use it. I’m used to Arduino, and this is just a huge leap for me. Thanks in advance!

Are you using a cRIO on the robot? If so, then just use TCP/IP over WiFi or Ethernet. You can use Processing’s Network library to do this: http://processing.org/reference/libraries/net/index.html It’s not the most efficient method, but you could send a list of numeric values as a comma-delimited string.

Alternately - I’ve never used Processing, but since it’s Java-based - you should be able to use the Java API for WPILib’s NetworkTables: http://wpilib.screenstepslive.com/s/3120/m/7912/l/80205-writing-a-simple-networktables-program-in-c-and-java-with-a-java-client-pc-side

How would I establish the TCP/IP connection and set the two values being sent over to a simple X & Y value on the bot to drive it? Like I said, all of this is new to me. I know basic c++, but I don’t know the syntax of these operations.

…If you’re really new to this all, and you’re using the typical cRIO-router communication setup, I would recommend that you get the robot functioning the traditional method by using the DriverStation. Once you thoroughly understand that, then you should move on to using Processing.

I’m planning on releasing a compilation of Processing sketches for creating a custom dashboard sometime before the season begins which will include demonstration projects which implement live video streaming, data storing, network tables, tcp/udp sockets, using the keyboard and mouse to control certain robot functions, vision processing, and so on. Of those things, the only one I have left to perfect is vision processing. I’m doing my best to comment and describe each and every programme so that they’re easily understandable, so that’s also eating up a lot of the time I’m spending on the project…

That was a bit off-topic… could you describe your setup in detail?

I’m just modifying the code I wrote for a practice bot. I want to replace the joystick x&y variables with the x&y variables being sent from processing. I understand the the workstation, I just don’t know how to setup up the connection between the cRIO and PROCESSING , and how to separate a comma-delimited string and make those values.

This is my original code that i’m modifying:

#include "WPILib.h"

class Stan : public IterativeRobot {

Jaguar *leftFront;
Jaguar *leftRear;
Jaguar *rightFront;
Jaguar *rightRear;

Joystick *driveStick;

Encoder *leftEncoder;
Encoder *rightEncoder;

Solenoid *shifter;


Gyro *moeGyro;

Compressor *moeCompressor;

DriverStation *ds;

DriverStationLCD *dsLCD;

int teleopLoop;
int disabledLoop;
int autoLoop;

public:
	
	Stan(void)			{
			
			leftFront = new Jaguar(1);
			leftRear = new Jaguar(2);
			rightFront = new Jaguar(3);
			rightRear = new Jaguar(4);
			
			driveStick = new Joystick(1);
			
			leftEncoder = new Encoder(1,2,true,Encoder::k1X);
			rightEncoder = new Encoder(3,4,false,Encoder::k1X);

			moeGyro = new Gyro(1);
			
			moeCompressor = new Compressor(7,1);
			
			ds = DriverStation::GetInstance();
			
			dsLCD = DriverStationLCD::GetInstance();
			
	}
			
	void RobotInit(void)	{
				
		leftEncoder->Start();
		rightEncoder->Start();
				
		moeCompressor->Start();
					
		shifter->Set(false);
	}

	void DisabledInit(void)		{

		disabledLoop = 0;
		
	}
	
	void TeleopInit(void)	{
	
		teleopLoop = 0;
	
	}

	void AutonomousInit(void)	{
		
		autoLoop = 0;
		
		leftEncoder->Reset();
		rightEncoder->Reset();
		
		moeGyro->Reset();
	
	}
	
	void DisablePeriodic(void)	{
		
		disabledLoop = disabledLoop +1;
	
	}
	
	void TeleopPeriodic(void)	{
		
		teleopLoop++;
		
		float X = driveStick->GetX();
		float Y = driveStick->GetY();
		
		if (X<0.1 && X>0.1)	X = 0.0;
		
		if (Y<0.1 && Y>0.1)	Y=0.0;
		
		X = Y + X;
		Y = X - Y;
		
		moeDrive(X, Y);
		
		controlShifter();
		
		int leftDist = leftEncoder->GetRaw();
		
		if (teleopLoop % 10==0)	{
			dsLCD->Printf(DriverStationLCD::kUser_Line1, 1, "L = %d", leftDist);
			
			dsLCD->UpdateLCD();
		}
	
	}
		
	void AutonomousPeriodic(void)	{
		
		autoLoop++;
		
		if (ds->GetDigitalIn(1))	{
			autoLoop++;
		}
	
	}
	
	void controlShifter(void)	{
		if (driveStick->GetTrigger())	{
			shifter->Set(true);
			}
		else	{
			shifter->Set(false);
			}
	}
	void moeDrive(float leftSpeed, float rightSpeed)	{
		
		if (leftSpeed > 1.0) leftSpeed = 1.0;
		else if (leftSpeed < -1.0) leftSpeed = -1.0;

		if (rightSpeed > 1.0) rightSpeed = 1.0;
		else if (rightSpeed < -1.0) rightSpeed = -1.0;
		
		leftFront->Set(leftSpeed);
		leftRear->Set(leftSpeed);
		rightFront->Set(rightSpeed);
		rightRear->Set(rightSpeed);
	}
	
};

START_ROBOT_CLASS(Stan);

You should take a look at this thread, as it discusses TCP/IP communication with WindRiver C++: http://www.chiefdelphi.com/forums/showthread.php?t=100810

Mentioned within is Team 3574’s 2012 code, which used a TCP to send vision data from the driver station laptop. Here’s a link: https://github.com/jacob9706/HighTekerz2012. You might be able to use it as a starting point.

Thanks for the extra bold extra italicized clarification. Sorry, sir, but I don’t believe I know the solution to your problem.

You can also check out the Network Tables code in the WPILib source code, which includes a TCP server. VxWorks looks like it basically uses the Berkeley/POSIX sockets API, so any resources on the Internet for Linux or Unix socket code should work as well. The code is a little extensive to replicate in-thread.

As for parsing delimited strings, here’s some code for that separates numbers delimited by whitespace:

Parse whitespace-delimited numbers

#include <string>
#include <sstream>
#include <iterator>
#include <vector>

#include <iostream>

int main(int argc, char **argv)
{
	if (argc != 2)
		return 1;
	
	std::string input(argv[1]);
	std::stringstream ss(input);
	std::vector<double> parts((std::istream_iterator<double>(ss)), (std::istream_iterator<double>()));
	if (ss.fail() && !ss.eof())
	{
		std::cout << "Data format error" << std::endl;
		return -1;
	}
	
	for(int i=0; i < parts.size(); ++i)
	{
		std::cout << parts* << std::endl;
	}
	
	return 0;
}

if you need comma to be delimiters as well, the code gets a bit more complicated:

Parse comma- and whitespace-delimited numbers

#include <string>
#include <sstream>
#include <vector>
#include <cctype>

#include <iostream>

int main(int argc, char **argv)
{
	if (argc != 2)
		return 1;
	
	std::string input(argv[1]);
	std::stringstream ss(input);
	std::vector<double> parts;
	double val;
	
	while(ss >> val)
	{
		parts.push_back(val);
		
		while(std::isspace(ss.peek()) || ss.peek() == ',')
			ss.ignore();
	}
	if (!ss.eof())
	{
		std::cout << "Data format error" << std::endl;
		return -1;
	}
	
	for(int i=0; i < parts.size(); ++i)
	{
		std::cout << parts* << std::endl;
	}
	
	return 0;
}

**