|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
|||
|
|||
|
counting in seconds for the autonomous mode??
hi there,,,
does any one knows how to convert the cycles of the autonomous mode 26.2ms to like actual seconds to keep a counter in seconds??? Thnx Rockie team help plz competition in 2 days ![]() |
|
#2
|
|||||
|
|||||
|
Re: counting in seconds for the autonomous mode??
Here's some code I wrote that we never used. Basicly, you follow the table and it shows you how many ticks or loops is equal to X number of seconds. You set the timer by calling auton_timer_1_start(), pass the number of ticks (loops) it should wait. In your code you can check if the time has passed by using something like this:
Code:
if (auton_timer_1()) {
// Time has been reached
} else {
// Still cycling, time has not been reached
}
Code:
// Start prototypes
unsigned char auton_timer_1();
void auton_timer_1_start(unsigned int time);
// End Prototypes
// Variables needed
unsigned int auton_timer_1_current = 0; // Is updated every 26.2ms loop when using timer 1
unsigned int auton_timer_1_limit = 0; // Is the time limit, which gets set by auton_timer_1_start()
// Done with variables
/* ################################ Start Timer Table ########################
1s/26.2ms =~ 38 ticks/s
I.E: If you want a 1 second timer, you must set the timer for 38 ticks.
-= Seconds =- -= Ticks =-
0.25 10
0.50 19
0.75 29
1.00 38
1.25 48
1.50 57
1.75 67
2.00 76
2.25 86
2.50 95
2.75 105
3.00 115
3.25 124
3.50 134
3.75 143
4.00 153
4.25 162
4.50 172
4.75 181
5.00 191
############################### End Timer Table ################ */
/* ******************************************************************************
* FUNCTION NAME: auton_timer_1_start
* PURPOSE: Set and start timer 1
* CALLED FROM: anywhere
* ARGUMENTS: time limit (unsigned int)
* RETURNS: void
****************************************************************************** */
void auton_timer_1_start(unsigned int time) {
auton_timer_1_current = 0;
auton_timer_1_limit = time;
return;
}
/* ******************************************************************************
* FUNCTION NAME: auton_timer_1
* PURPOSE: Checks timer 1 to see if limit has been reached.
* CALLED FROM: anywhere
* ARGUMENTS: none
* RETURNS: TRUE if limit has been reached, FALSE if time has not expired
****************************************************************************** */
unsigned char auton_timer_1(void) {
++auton_timer_1_current;
if (auton_timer_1_current >= auton_timer_1_limit) {
return 1;
} else {
return 0;
}
}
Last edited by MikeDubreuil : 30-03-2004 at 16:34. |
|
#3
|
|||||
|
|||||
|
Re: counting in seconds for the autonomous mode??
Quote:
Code:
#define MS *4
void User_Autonomous_Code(void)
{
unsigned int clicks; /* 4000 clicks per second theoretical, 4007.63358779 clicks actual :-) */
clicks = 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! */
if (clicks < 16000 MS)
clicks += 105; /* 26.2 more milliseconds have elapsed, this count will be fast by just over 0.19% */
else
clicks = 16000 MS; /* peg at 16 seconds */
/* Add your own autonomous code here. */
User_Mode_byte = clicks/400;
Generate_Pwms(pwm13,pwm14,pwm15,pwm16);
Putdata(&txdata); /* DO NOT DELETE, or you will get no PWM outputs! */
}
}
}
The User_Mode_byte on the OI counts in tenths of a second while the autonomous function is running. |
|
#4
|
|||
|
|||
|
Re: counting in seconds for the autonomous mode??
First: Feel Free to Re-Organize IFI's Autonomous Code
You may want to back up a little bit. Note that the only reason that loop is 26.2 ms is because of that Getdata. You only need to call Getdata when that statusflag.NEW_SPI_DATA flag gets set. Thus, if you organize your code well, you can run much faster cycles in autonomous mode. That may or may not be helpful to you. Additionally, someone's mentioned how you should put the Generate_Pwms in autonomous mode as well before the Putdata call. You might think about replacing the whole thing with Process_Data_From_Local_IO, and now that I think about it, you should probably put that P_D_F_L_IO outside the slow if( statusflag... ) block. That way you'll be able to respond to robot sensors much more quickly in the exact same fashion as you respond to sensors in non-autonomous mode. Don't Use the 26.2 ms Cycles to Count Time Now, that being the case, I would not recommend using the 26.2 ms flag for timing. If you wanted to, you could count down from 38, decrementing once a cycle, and every time you hit 0 you would have gone ABOUT 1 second. But there are better ways to doing things. Use the PIC Counters to Keep Time for You (with Interrupts) I'm fairly sure that the student who did most of the coding for the robot found instructions on IFI's website on how to configure the counters to keep time for the robot. Right now, I can't find where he found it, but I can show you the simple example in our own code: http://www.osufirst.org/twiki/bin/vi...04RegionalCode You'll see that WE MUST INCLUDE timers.h. This is a SYSTEM INCLUDE, so you'll have to include it with less-than and greater-than braces rather than quotes. After this, it's fairly easy to configure a timer which produces an interrupt every 100th of a second (you can change this to faster or slower rates, but our code is configured for 100ths of a second). Look at the interrupt handler in user_routes_fast.c. You'll see that AT THE VERY BOTTOM OF IT, it increments an elapsedTime and also sets a timeUpdate. elapsedTime is our on-board "clock." Every second, it sees an increment of 100. timeUpdate is a variable we use to communicate that a new "count" just occurred, letting some of our other routines do some "sampling." That's another story. We also had to add code to the Initialize routine to configure the counter. After all this, it was about 5 lines of code, and we could count on (no pun intended) elapsedTime keeping an "on-board clock" for us. I'd recommend doing something like this in your setup. |
|
#5
|
|||||
|
|||||
|
Re: counting in seconds for the autonomous mode??
Quote:
|
|
#6
|
|||
|
|||
|
Re: counting in seconds for the autonomous mode??
Quote:
http://www.innovationfirst.com/FIRST...10-29-2003.pdf on IFI's website. In particular, you see that PutData() will handle PWMs 1-12, (slow PWMs) and those can only be changed every 26ms. While 13-16 are the fast PWMs that can be changed more often (every 2 ms). IFI's website is very clear that PutData and Generate_Pwms(13-16) can be called as quickly as possible, but G_Pwms is the only thing that generates those PWMs that quickly. It warns that devices connected to the PWM outputs may have trouble with the fast changing PWM outputs and to check those device specifications, but there's nothing about the RC that makes this a bad idea. After all, aren't Putdata and Generate_Pwms called in the default fast routines anyway? |
|
#7
|
||||
|
||||
|
Re: counting in seconds for the autonomous mode??
Well, we have had problems when using those generated PWMs, especially if they are called quickly. We've observed fluctuations in the motor we're trying to adjust as well as induced outputs on other PWMs that are generated. Switching to PWMs 1-12 solved these problems.
While it may not be a bad idea in theory to call G_PWMs quickly, for practical application with the robots we are building, its unnecessary and possibly detrimental. Do you really need to update your actual motor output at faster than 38hz? |
|
#8
|
||||
|
||||
|
Re: counting in seconds for the autonomous mode??
Quote:
Code:
auton_time++; ?! you gotta remember lots of students are struggling just to understand this stuff, and dont normally use uP hardware everyday :^) |
|
#9
|
|||
|
|||
|
Re: counting in seconds for the autonomous mode??
would this code work u think?? we're going to use a stopwatch to determine how long it actually takes us in average. the only think we are doing in autonomous mod is driving to the 10 pt ball and hopefully noking it down.
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 */ { counter++; Getdata(&rxdata); /* DO NOT DELETE, or you will be stuck here forever! */ /* Add your own autonomous code here. */ // counter calculated as (38*12) if ( counter < 456 ) // still less than 12 seconds have elapsed { if (rc_dig_in01 == 0 && rc_dig_in02 == 0) { pwm13 = pwm14=137; pwm15= pwm16= 137; } if (rc_dig_in01 == 1 && rc_dig_in02 ==0) { pwm13 = pwm14= 128; pwm15= pwm16= 132; } if (rc_dig_in01 ==0 && rc_dig_in02 == 1) { pwm13 = pwm14=132; pwm15= pwm16=128; } } Generate_Pwms(pwm13,pwm14,pwm15,pwm16); Putdata(&txdata); /* DO NOT DELETE, or you will get no PWM outputs! */ } } } |
|
#10
|
|||||
|
|||||
|
Re: counting in seconds for the autonomous mode??
Quote:
I might add an initialization for counter, e.g., Code:
void User_Autonomous_Code(void)
{
unsigned int counter=0;
...
while (autonomous_mode) /* DO NOT CHANGE! */
Even if you initialized counter when you declare it, e.g., static unsigned int counter=0; You'll have trouble during the practice sessions when you run twice in a row. You'd have to be sure to reset the RC between runs. Explicitly setting it before the auto loop avoids this potential pitfall. [edit] Actually "static" isn't required in this case, since you never leave the routine. I only tend to use it as a matter of convention (Our functions aren't written to take control away from the main loop). You can in this case declare "unsigned int counter=0;" in the local routine and be fine. I still prefer explicit initialization though. Last edited by Mark McLeod : 31-03-2004 at 11:49. |
|
#11
|
||||
|
||||
|
Re: counting in seconds for the autonomous mode??
Quote:
BTW at most regionals they have a carpet setup in a back hallway where you can test your auton code - you usually have to sign up for a time slot, but it really helps to be able to test it, tweak your code, test it again... it looks good - your on the right path. |
|
#12
|
|||||
|
|||||
|
Re: counting in seconds for the autonomous mode??
Quote:
Quote:
|
|
#13
|
|||||
|
|||||
|
Re: counting in seconds for the autonomous mode??
Regarding pwm13-16: See this thread, and see Kevin Watson's FAQ especially the first really long question.
I stay away from PWM13-16. 38 Hz is fast enough for me! |
|
#14
|
||||
|
||||
|
Re: counting in seconds for the autonomous mode??
hmmmm.... I dont understand TedPs adversion to counting SW loops.
someone has tested the timing of the statusflag.NEW_SPI_DATA event- its controlled by a timer in the communications loop and testing has shown its dead accurate every time, unless you have so much code that it takes more than 26mS seconds to execute. statusflag.NEW_SPI_DATA will be true 38 times a second - you can even round it off to 40 to make it simpler - I cant imagine anyone needing finer resolution that 1/38th of a second while setting up the sequence of events in auton mode ? |
|
#15
|
|||
|
|||
|
Re: counting in seconds for the autonomous mode??
Quote:
Having interrupt-controlled timing that is triggered by an interrupt generated by the terminal count of a hardware timer timed fairly precisely to go off every 100th of a second (or even finer) seems much simpler than using a counter to do this timing. Additionally, you can use this counter later on in your competition mode code. It just seems much cleaner to have an interrupt manage all your timing for you. You can get fairly fine time resolution, and you don't have to worry about making sure you increment in time. Run code as slow as you'd like; the interrupt will jump in when it needs to increment your "clock." If you do things the more naive way, then you gain a second every twenty seconds, and you lose the ability to differentiate in time among a great number of cycles of your code. That may not be that big of a deal, but it definitely could use some improvement. Using the simple interrupt-driven timing does this. That's all I'm saying. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Future of Autonomous Mode | FadyS. | Programming | 41 | 24-05-2004 19:45 |
| Simple Autonomous Mode Example | deltacoder1020 | Programming | 5 | 08-03-2004 20:22 |
| Initializing autonomous mode | Mr. Lim | Programming | 7 | 02-02-2004 07:26 |
| autonomous mode problem on field | Chris_C | Programming | 17 | 26-03-2003 19:11 |
| autonomous mode timer | Don | Programming | 6 | 09-02-2003 22:16 |