Controlling Drive With 2 Controllers


#1

I was wondering what kind of code does it take so that two drivers can independently move the drive base?

For instance: Controller A controls the drive base and ball launcher. Then Controller B controls the arm, cap flipper and drive base.

When we tried to do this, the drive base wouldn’t work and some of the words either didn’t move it twitched when certain joysticks were moved.

Any help is appreciated. Thank you!!!


#2

So if you wanted to code on joystick axis 1 you would use Ch1Xmtr2 for the second controller instead of Ch1 which is the first controller

posting your code also helps


#3

If you send differing commands to a motor in rapid succession, it will do strange things. Make sure that the drive motors are only being controlled by one driver at a time, or come up with a system to share control. One way to ensure a single driver at a time could be allowing either driver to take control while neither are sending drive base commands, but then locking the other driver out until the first driver has released the joysticks.


#4

We thought that putting a threshold in there to create a dead zone would help.

Haven’t tested this code out but we think it could work.

#pragma config(Motor,  port1,           RightFrontDrive, tmotorVex393HighSpeed_HBridge, openLoop, reversed, driveRight)
#pragma config(Motor,  port2,           RightMiddleDrive, tmotorVex393HighSpeed_MC29, openLoop, reversed, driveRight)
#pragma config(Motor,  port3,           RightBackDrive, tmotorVex393HighSpeed_MC29, openLoop, reversed, driveRight)
#pragma config(Motor,  port8,           LeftFrontDrive, tmotorVex393HighSpeed_MC29, openLoop, driveRight)
#pragma config(Motor,  port9,           LeftMiddleDrive, tmotorVex393HighSpeed_MC29, openLoop, driveRight)
#pragma config(Motor,  port10,          LeftBackDrive, tmotorVex393HighSpeed_HBridge, openLoop, driveRight)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task main()
{
	int threshold = 20;
	int mainCh2;
	int mainCh3;
	int partnerCh2;
	int partnerCh3;

	while(true) {

		// Record the stick values.
		mainCh2 = vexRT[Ch2];
		mainCh3 = vexRT[Ch3];
		partnerCh2 = vexRT[Ch2Xmtr2];
		partnerCh3 = vexRT[Ch3Xmtr2];

		if(abs(mainCh2) < threshold && abs(mainCh3) < threshold)
		{ // if main is not in use, use partner controls
			if(partnerCh2 < threshold)
			{
				// check the dead band for the left stick
				motor[LeftFrontDrive] = 0;
				motor[LeftMiddleDrive] = 0;
				motor[LeftBackDrive] = 0;
			}
			else
			{
				motor[LeftFrontDrive] = partnerCh2;
				motor[LeftMiddleDrive] = partnerCh2;
				motor[LeftBackDrive] = partnerCh2;
			}
			if(partnerCh3 < threshold)
			{ // check the dead band for the right stick
				motor[RightFrontDrive] = 0;
				motor[RightMiddleDrive] = 0;
				motor[RightBackDrive] = 0;
			}
			else
			{
				motor[RightFrontDrive] = partnerCh3;
				motor[RightMiddleDrive] = partnerCh3;
				motor[RightBackDrive] = partnerCh3;
			}
		}
		else
		{ // if any main stick is in use, let main controller dominate
			if(mainCh2 < threshold)
			{ // check the dead band for the left stick
				motor[LeftFrontDrive] = 0;
				motor[LeftMiddleDrive] = 0;
				motor[LeftBackDrive] = 0;
			}
			else
			{
				motor[LeftFrontDrive] = mainCh2;
				motor[LeftMiddleDrive] = mainCh2;
				motor[LeftBackDrive] = mainCh2;
			}
			if(mainCh3 < threshold)
			{ // check the dead band for the right stick
				motor[RightFrontDrive] = 0;
				motor[RightMiddleDrive] = 0;
				motor[RightBackDrive] = 0;
			}
			else
			{
				motor[RightFrontDrive] = mainCh3;
				motor[RightMiddleDrive] = mainCh3;
				motor[RightBackDrive] = mainCh3;
			}
		}
	}
}


#5

I see one issue, and you already solved it in one instance.


if(partnerCh2 < threshold)

Since this is used, any value below the threshold (20) wouldn’t be counted, which will be a problem when attempting to drive backwards (i.e. -127). This can be fixed by simply adding an absolute value around partnerCh2 and similar entries, like you did in the very first if loop.


#6

How about this? Also make sure you paste the code in the competition template as well if you’re competing.
(Sorry for bad syntax vexforum doesn’t support pressing tab)


#pragma config(Motor,  port1,           RightFrontDrive, tmotorVex393HighSpeed_HBridge, openLoop, reversed, driveRight)
#pragma config(Motor,  port2,           RightMiddleDrive, tmotorVex393HighSpeed_MC29, openLoop, reversed, driveRight)
#pragma config(Motor,  port3,           RightBackDrive, tmotorVex393HighSpeed_MC29, openLoop, reversed, driveRight)
#pragma config(Motor,  port8,           LeftFrontDrive, tmotorVex393HighSpeed_MC29, openLoop, driveRight)
#pragma config(Motor,  port9,           LeftMiddleDrive, tmotorVex393HighSpeed_MC29, openLoop, driveRight)
#pragma config(Motor,  port10,          LeftBackDrive, tmotorVex393HighSpeed_HBridge, openLoop, driveRight)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task main(){
	int threshold = 20;
while(1==1){

//Left Side
if( abs(vexRT[Ch3Xmtr2]) <threshold && abs(vexRT[Ch3]) <threshold){
	motor[LeftFrontDrive] = 0;
	motor[LeftMiddleDrive] = 0;
	motor[LeftBackDrive] = 0;
}

else{
	motor[LeftFrontDrive] = vexRT[Ch3Xmtr2] + vexRT[Ch3];
	motor[LeftMiddleDrive] = vexRT[Ch3Xmtr2] + vexRT[Ch3];
	motor[LeftBackDrive] = vexRT[Ch3Xmtr2] + vexRT[Ch3];
}

//Right Side
if( abs(vexRT[Ch2Xmtr2]) <threshold && abs(vexRT[Ch2]) <threshold){
	motor[RightFrontDrive] = 0;
	motor[RightMiddleDrive] = 0;
	motor[RightBackDrive] = 0;
}

else{
	motor[RightFrontDrive] = vexRT[Ch2Xmtr2] + vexRT[Ch2];
	motor[RightMiddleDrive] = vexRT[Ch2Xmtr2] + vexRT[Ch2];
	motor[RightBackDrive] = vexRT[Ch2Xmtr2] + vexRT[Ch2];
}

}//End of While Loop

}// End of Task


#7

I would recommend against that. You’re giving both drivers control of the motors at the same time. Not only that, you’re including in that combination what should be dead zones based on your threshold. For example, let’s say the partner joystick sits at -15 on channel 2 and +15 on channel 3. When both people do nothing, no problem. But when the main controller tries to drive, the robot will always tend to veer in the same direction, which will be awkward to control and will cap your maximum straight-line speed. The originally provided method, outside of forgetting abs() in some spots, is far superior for what it’s trying to do.


#8

Ah, good point. I see.
What about this?


#pragma config(Motor,  port1,           RightFrontDrive, tmotorVex393HighSpeed_HBridge, openLoop, reversed, driveRight)
#pragma config(Motor,  port2,           RightMiddleDrive, tmotorVex393HighSpeed_MC29, openLoop, reversed, driveRight)
#pragma config(Motor,  port3,           RightBackDrive, tmotorVex393HighSpeed_MC29, openLoop, reversed, driveRight)
#pragma config(Motor,  port8,           LeftFrontDrive, tmotorVex393HighSpeed_MC29, openLoop, driveRight)
#pragma config(Motor,  port9,           LeftMiddleDrive, tmotorVex393HighSpeed_MC29, openLoop, driveRight)
#pragma config(Motor,  port10,          LeftBackDrive, tmotorVex393HighSpeed_HBridge, openLoop, driveRight)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task main(){
	int threshold = 20;
	int mastercontrol = 1;//This would be used to determine when the master controller is being ran

//Create Chan2 and Chan3, and set the initial value to 0 to have a value in case joystick wasn't connected.
int Chan2 = 0;
int Chan3 = 0;

while(1==1){

//This would be used to allow the master controller to override the slave controller when the
//master controller is outside of the threshold
if(abs(vexRT[Ch2])<threshold &&abs(vexRT[Ch3])<threshold){
mastercontrol = 0;
}
else{
mastercontrol = 1;
}

//If the master controller joystick values are above the threshold, override slave
if(mastercontrol == 1){

//Apply Chan3 to the master channel 3
Chan3 = vexRT[Ch3];
//Set Chan3 to 0 if channel 3 is within threshold
if(abs(vexRT[Ch3])<threshold) Chan3 = 0;


//Apply Chan2 to the master channel 2
Chan2 = vexRT[Ch2];
//Set Chan2 to 0 if channel 3 is within threshold
if(abs(vexRT[Ch2])<threshold) Chan2 = 0;

}

//Enable the slave controller
else{

//Apply Chan3 to the slave channel 3
Chan3 = vexRT[Ch3Xmtr2];
//Set Chan3 to 0 if channel 3 is within threshold
if(abs(vexRT[Ch3Xmtr2])<threshold) Chan3 = 0;


//Apply Chan2 to the slave channel 2
Chan2 = vexRT[Ch2Xmtr2];
//Set Chan2 to 0 if channel 3 is within threshold
if(abs(vexRT[Ch2Xmtr2])<threshold) Chan2 = 0;

}

	motor[LeftFrontDrive] = Chan3 ;
	motor[LeftMiddleDrive] = Chan3 ;
	motor[LeftBackDrive] = Chan3 ;

	motor[RightFrontDrive] = Chan2 ;
	motor[RightMiddleDrive] = Chan2 ;
	motor[RightBackDrive] = Chan2 ;

}//End of While Loop

}// End of Task