We are having a problem. When we uncomment the Default_Routine our drives will not work in auto mode. But it will work with the joystick. If we leave it commented out, it will work in auto mode to drive the wheels, but the joystick will not drive the wheels when we come out of auto mode. Are we missing something?
Also, does anyone know the PWM outputs for the pan and tilt server in Kevin’s “bells and whistles” 2.1 code? Is it the same as 2.0?
What do you have for autonomous code? There is no default autonomous. Anything you see there when you get the code should not be deleted. The Default_Routines function cannot be used in autonomous, due to its nature of interfacing with the joysticks and user input. Calling this function during autonomous is bad.
The default_Routines implementation is commented out for safety reasons. Scour the comments until you see the comment describing this, and follow the instructions. Un-commenting the function worked for us…
I can’t comment further until I know the nature of your autonomous code. This seems to be a code problem.
When you say “our drives”, do you mean the pwm motors? All input from the user is disabled during autonomous to keep to its namesake.
Yes, we mean our drives. Example of our Auto mode:
{
if(Get_Tracking_State() == TARGET_IN_VIEW) /* make sure camera is tracking /
{
if(((((int)PAN_SERVO - 124) * 65)/124) > 20) / check current pan servo position. 0 > is right, 0 < is left /
{
pwm15 = 167; / do a left turn /
pwm13 = 87;
}
else if(((((int)PAN_SERVO - 124) * 65)/124) < -20)
{
pwm15 = 87; / do a right turn */
pwm13 = 167;
}
else
{
pwm13 = 167;
pwm15 = 167;
}
}
This will work fine in Auto Mode (camera tracks, drives work perfectly) when we comment out the Default_Routine in user_routines.c file to look like this (// Default_Routine). Then when we try to use the joysticks after auto mode we cannot. If we go to user_routines.c file and uncomment out the Default_Routine this does not work and the joysticks work perfectly. What are we missing? Thanks for your help. If you don’t want to put code on here send me a private message and we can talk that way. Thanks…
Your problem may be that you are using PWMs 13-16 but are not generating the PWM signals for those ports.
If you are using Kevin’s 2007 code, you must call the PWM(pwm13, pwm14, pwm15, pwm16) function as the very last line, just before the PutData() line.
If you are using IFI’s code, you must call Generate_Pwms(pwm13, pwm14, pwm15, pwm16) in that place.
make sure you are using the correct PWM function. I would say for debugging purposes to use PWM’s 9-12 or something like that, to make sure that it in fact is not the generated pwms that are the problem.
There could be many other problems as well… unfortunately I can’t think of much else without seeing your entire loop in your Autonomous_Routine()
It sounds like you’re executing your autonomous code and immediately following with Default_Routine() in user_routines.c. The last one to be executed will set your pwm outputs and win.
How are you entering Autonomous mode?
Via a Competition Port dongle or one of the other possible methods?
Where have you placed your autonomous code?
In user_routines_fast.c’s User_Autonomous_Code()?
A much cleaner way to do that (and more precise) would be to have a proportional algorithm and as the degree value gets closer to 0 move less, farther from 0 moves more, etc.
Mark…
How are you entering Autonomous mode? We are entering the Auto mode in user_routines_fast.c where they tell us to enter our code.
Via a Competition Port dongle or one of the other possible methods? Dongle switch…
Where have you placed your autonomous code? answered above.
In user_routines_fast.c’s User_Autonomous_Code()? Yes…
Everything works perfectly in Auto mode, but when we come out of Auto mode the drives don’t work with the joysticks???..
This change causes the auto mode to work, but the joysticks do not. Remember the drives are wired to pwm13 and pwm15… Looks like this should have nothing to do with it???
Do i understand correctly that you started with Kevin Watson’s “bells and whistles” 2.1 code?
Used as is there seem to be conflicting calls to set PWMs 13,14,15,16 mixing a new method Kevin’s introduced with an older unreliable method. Just an oversight.
In User_Autonomous() replace:
Generate_Pwms(pwm13,pwm14,pwm15,pwm16);
with
PWM(pwm13,pwm14,pwm15,pwm16);
P.S. You also need to add #include “pwm.h” to user_routines_fast.c
There is also some extra code you should probably comment out in Default_Routine() just before pwms13,14,15,16 are set:
p1_x = 255 - p1_y;
p1_y = 255 - pwm05;
You might also try testing your output on pwms other than 13-16.
P.S. Remember you have to copy the camera calls from user_routines.c into your autonomous routine to keep the camera running during autonomous.
Thanks Mark. I’ll try this when I get my hands on the robot. I’ll let you know if it works. I agree with you Kevin, this really through us for a loop. (No pun intended…) Thanks again guys…
I’ve had TONS of trouble trying to figure out how their one-joystick drive code works. Our robot won’t drive correctly if I take that bit out (because of the way one motor is mounted “backwards”), but in all the testing I do on the computer, the numbers come out way wrong.
Commenting out those two lines shouldn’t change anything, should it? Because it keeps me from driving…
Those two extra lines will make the joystick mixing act as if the motors are not reversed and are all oriented the same way on the robot.
Based on what you’re seeing I’d guess since your motors are reversed, as is the case for the vast majority of our FIRST robots, then the wiring on your Victor(s) for one drive side is reversed (on the motor output side).
You can leave that code in to correct for the reversed wiring job, however, purely as a matter of personal opinion, I consider reversing the meaning of the x and y axis to be poor technique. You can accomplish the same thing without adding confusion by just reversing the p1_x and p1_y terms in the mixing equation.
The User_Autonomous_Code() routine is called when you enter autonomous mode and you can just add your own driving code for it to work as it is.
If you are depending on using the camera then you’ll need to add camera calls as found in Process_Data_From_Master_uP() to User_Autonomous_Code().
Mark we are still having the same problem. I did everything you instructed me to do and the problem still exists. The camera performs perfectly when we use Kevin’s default 2.1 code with nothing added. Starting from scratch: If I put my code in the Autonomous loop where the code tells us to place it, the camera will not track anymore when we use the dongle and try to enter autonomous mode. The camera seems to go to a home position and stop.
Example:
void User_Autonomous_Code(void)
{
/* Initialize all PWMs and Relays when entering Autonomous mode, or else it
will be stuck with the last values mapped from the joysticks. Remember,
even when Disabled it is reading inputs from the Operator Interface.
*/
pwm01 = pwm02 = pwm03 = pwm04 = pwm05 = pwm06 = pwm07 = pwm08 = 127;
pwm09 = pwm10 = pwm11 = pwm12 = pwm13 = pwm14 = pwm15 = pwm16 = 127;
relay1_fwd = relay1_rev = relay2_fwd = relay2_rev = 0;
relay3_fwd = relay3_rev = relay4_fwd = relay4_rev = 0;
relay5_fwd = relay5_rev = relay6_fwd = relay6_rev = 0;
relay7_fwd = relay7_rev = relay8_fwd = relay8_rev = 0;
while (autonomous_mode) /* DO NOT CHANGE! /
{
if (statusflag.NEW_SPI_DATA) / 26.2ms loop area /
{
Getdata(&rxdata); / DO NOT DELETE, or you will be stuck here forever! */
/* Add your own autonomous code here. */
if(Get_Tracking_State() == TARGET_IN_VIEW) /* make sure camera is tracking */
{
if(((((int)PAN_SERVO - 124) * 65)/124) > 20) /* check current pan servo position. 0 > is right, 0 < is left */
{
pwm15 = 167; /* do a left turn */
pwm13 = 87;
}
else if(((((int)PAN_SERVO - 124) * 65)/124) < -20)
{
pwm15 = 87; /* do a right turn */
pwm13 = 167;
}
else
{
pwm13 = 167;
pwm15 = 167;
}
Generate_Pwms(pwm13,pwm14,pwm15,pwm16);
Putdata(&txdata); /* DO NOT DELETE, or you will get no PWM outputs! */
}
}
}
If I take out everything but my code in the Autonomous loop the camera will work fine and the robot will respond when we enter autonomous mode (everything is perfect), but when we exit autonomous mode the drives (wheels) will start running wildly and the joysticks will not work.
Example:
void User_Autonomous_Code(void)
{
if(Get_Tracking_State() == TARGET_IN_VIEW) /* make sure camera is tracking /
{
if(((((int)PAN_SERVO - 124) * 65)/124) > 20) / check current pan servo position. 0 > is right, 0 < is left /
{
pwm15 = 167; / do a left turn /
pwm13 = 87;
}
else if(((((int)PAN_SERVO - 124) * 65)/124) < -20)
{
pwm15 = 87; / do a right turn */
pwm13 = 167;
}
else
{
pwm13 = 167;
pwm15 = 167;
}
}
I’m restating my answer to more directly address your two examples.
In your first example I’m sure you’ve noticed that the Autonomous routine runs instead of the main loop where the camera operational functions are called in Process_Data_From_Master_uP(). "while (autonomous_mode) " keeps the code from going back to main() until autonomous_mode is over.
So your normal camera operation calls are no longer being made when you flip the dongle switch.
To make the first example work you’ll have to modify the Autonomous routine by copying the camera calls from Process_Data_From_Master_uP() to your Autonomous routine. e.g.,
Camera_Handler();
Servo_Track();
and optionally for feedback:
Tracking_Info_Terminal();
if(Get_Tracking_State() == CAMERA_ON_TARGET)
{
Switch3_LED = 1;
}
else
{
Switch3_LED = 0;
}
You can also accomplish the same thing by calling Process_Data_From_Master_uP() inside your autonomous loop - just be sure it’s called BEFORE you set your pwm outputs since the buried call to Default_Routine() would override your pwm values.
Your second example is a valid approach as well (it’s how I tend to do it).
Have you modified main() at all?
Removing the "while (autonomous_mode) " loop and the Getdata/Putdata calls as you did, so you always return to main(), allows Process_Data_From_Master_uP() to be called as it normally is.
If you walk through the sequence of how things are called you’ve probably seen that Default_Routine() will get called before the Autonomous routine. So if you haven’t modified main() while in autonomous mode you are setting the motors based on the joysticks then overriding those settings with the subsequent call to User_Autonomous_Code().
It’s a little dangerous to call both Default_Routine() and User_Autonomous_Code(). If you don’t set EVERY output in the last routine called you can end up with quite a mixed bag of outputs. I’d redesign it to call one or the other, not both, by pulling the call to Default_Routine() out of Process_Data_From_Master_uP() and using an “if else” to get either Default_Routine() or User_Autonomous_Code().
After leaving autonomous mode you should just stop overriding the pwm outputs, so something else is happening.
I suspect main() with no other evidence.