Okay stupid question. I’m on a rookie team and we have been having problems for a WEEK now on the basic driving code. We have a standard drive system, using 2 cim motors that go to 2 wheels each and want to use one joystick to control both motors, that go to pwm13 and pwm15. We have been having a lot of issues with the default code, since we want to have full proportional control wherever the joystick is. Could someone please post their drive code if they have a similar configuration? Thank you.
The default code has code for a 1 joystick drive? Can you explain what is wrong with this or what you want that is different from that?
Well my team wants to have straightforward code, not have the limiting function involved. I know why it is there, to make sure the bounds never fall outside of the unsigned int datatype, but is it possible to not have to use this (limit_mix) function?
One problem is that pwm’s 13-16 are generated in a special way, using the Generate_PWM function.
I would suggest trying pwm’s 10 and 11 for example (change the code)
In my opinion, the best way to debug PWM problems is to look at the light on the Victor itself:
(FYI: The Victor light is the most accurate source if you are stuck with a PWM value problem… that one light tells you a lot of info. If it is flashing orange, it’s a 3-pin PWM cable problem, or it’s set to a special value that disables it (like if your robot is detached). If it’s completely off once you run the code, the motors are running slowly or half-speed. If it’s solid orange, they are inside the deadband or completely stopped. If it’s bright red or green, it’s running full power in forward or reverse.)
Flashing orange could also mean a problem with the Generate_Pwm() or PWM() function calls if you are on 13-16… best to try switching to a different port if you aren’t sure.
Here’s a thread with a similar problem to the one you are having:
http://chiefdelphi.com/forums/showthread.php?t=52869
Alright…
Say, you have two cims on each side
each cim is connected to its own speed controller
CIM 1 and CIM 2 are on the left side and the speed controllers are connected to PWM 01 and PWM 02. CIM 3 and CIM 4 are on the right side and the speed controller are connected to PWM 03 and PWM 04
You will use two joysticks. One joystick will controll the left side and the other, the right side. Connect the joysticks to port 1 and port 2 on the OI.
In the code the joysticks return 0 to 255, the motors also work on 0 to 255 values. If you set the motor to 127 it is neutral, likewise the joystick is at 127 when it is at center. Since both the joystick and the motors work on the same range you can do a direct joystick to PWM… heres an example
PWM01 = p1_y;
PWM02 = p1_y;
PWM03 = 255 - p2_y;
PWM04 = 255 - p2_y;
Now, the joystick connected to port one (p1_y) (port 1 y axis) will control speed controller connected to PWM 01 and PWM 02… this will controll the left side… the same goes for the p2_y, however you must reverse it (255 - p2_y) since the motors are spinning the oppisite way…
Hope thats enough to get you started…
remember joysticks give values 0-255 and motors take values 0 - 255 and neutral is 127…
Good luck
You could try easyC and just use the Arcade 2-Motor drive block… One single drag and drop will do it.
I’m not sure if you want to go this route, but for an ‘easy’ solution, this is probably it.
Jacob
Thanks for the help, but coding 2 joysticks for 2 or 4 motors is about as simple as anything. And I understand how the victor’s work completely, I read the manual. I just wanted to see the code for someone’s drive system that uses 2 motors w/ 1 joystick that doesn’t use another function to limit the range of values to keep it within the bounds of the datatype unsigned int.
We don’t use the Limit_Mix function, but we do a similar operation. We do all of our math (for this functionality) in 16 bit integers, make sure that it’s in range (using a custom MIN_MAX macro), then store it into an output (conveniently aliased).
#define MAX(variable, max_val) if (variable > (max_val)) variable = (max_val)
#define MIN(variable, min_val) if (variable < (min_val)) variable = (min_val)
#define MIN_MAX(variable,min_val,max_val) MIN((variable),(min_val)); MAX((variable),(max_val))
.....
#define Oi_drive_x p1_x
#define Oi_drive_y p1_y
#define Rc_analog_out_drive_left pwm01
#define Rc_analog_out_drive_right pwm02
....
/* INT16 is typedef'd as int */
INT16 right_drive_speed, left_drive_speed;
/* single stick drive calculation */
left_drive_speed = ((INT16)Oi_drive_y - (INT16)Oi_drive_x + 127);
right_drive_speed = ((INT16)Oi_drive_y + (INT16)Oi_drive_x - 127);
MIN_MAX(left_drive_speed, 0, 254);
MIN_MAX(right_drive_speed, 0, 254);
.....
Rc_analog_out_drive_left = left_drive_speed;
Rc_analog_out_drive_right = right_drive_speed;
^^^^^
That looks like a long version of what we use. Try that out and see if it works, i was just about to post our long version of it
We use this code:
#define DEADZONE 10
signed int xturn = p1_x - 193;
signed int yspeed = p2_y - 127;
signed int turnspeed;
int percent;
pwm01 = pwm02 = p2_y;
printf("p1_x=%d
", p1_x);
printf("xturn=%d
", xturn);
if (!p1_sw_trig) {
if (xturn < -DEADZONE) { //turning right
percent = 100 * (-xturn - DEADZONE) / (41 - DEADZONE);
percent = (percent > 100) ? 100 : percent;
turnspeed = p2_y - yspeed * percent / 50;
printf("turning right=%d
", (int)turnspeed);
printf("Percent=%d
", (int) percent);
pwm02 = turnspeed;
} else if (xturn > DEADZONE){ //turning left
percent = 100 * (xturn - DEADZONE) / (41 - DEADZONE);
percent = (percent > 100) ? 100 : percent;
turnspeed = p2_y - yspeed * percent / 50;
pwm01 = turnspeed;
printf("turning left=%d
", (int)turnspeed);
printf("Percent=%d
", (int) percent);
}
}
Technically, this uses two joysticks, one that goes left-right and one that goes forward back.
It should be easy to modify this to work with your system. There are some considerations. The left-right joystick, because of how it’s set up, has a range from 127-255 instead of 0-255. This caused some odd calculations, such as the subtracting 193, the dividing by 41 - DEADZONE instead of 117 - DEADZONE, and the dividing by 50 instead of 100.
I’m sure you can make this work.
Well, our code converts joystick 0-255 to signed values in range -127 to +127.
The mixing function is then:
left speed = rotationaxis + directionaxis
right speed = rotationaxis - directionaxis
We add the 127 to the speeds only at the point where the speed values are output to the Victors.
(Basically - take the direction axis value and add the rotation to one wheel, and subtract the rotation from the other)
One of the problems I’ve noticed with trying to skid steer the typical 4 wheel drive robot is that simply backing off on the power on one side isn’t enough to get good steering control. The higher powered side can drag the robot along nearly straight. You have to drastically cut back on the power, stop, or even reverse the motor on the inside of the turn.