|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
||||
|
||||
|
Copy Cat
I haven't seen any threads about copycat in a while, so I figure I'll share what I know. My team used a simplified version of copycat for the past two years as a backup to the code we couldn't get working. It's quite simple.
The idea is that you push a button in user control mode, then it writes to EEPROM the values you send to your motors. In autonomous mode, you play back the recording and that's your autonomous mode. put this in your user_routines.c() Code:
void storemotors(void)
{
static char lr = 0;
if (lr==0) //alternate writing lmotor & rmotor
{
writeEE(address, lmotor); //writes the motor value to EEPROM
lr=1;
}else
{
writeEE(address, rmotor);
lr=0;
}//endif
address++; //increments address
}//end storemotors
char readEE(unsigned short address) {
// Load address into address register
EEADRH = ((address>>8)&0x03); //Bits 2-7 are masked off since EEPROM is only 1KB
EEADR =(address&0xFF);
//Configuration as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.RD =1;
return EEDATA;
}
void writeEE(unsigned short address, char data)
{
EEADRH = ((address>>8)&0x03);
EEADR =(address&0xFF);
EEDATA = data;
//Configuration as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.WREN =1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;
}
Code:
void readmotors(void)
{
static char lr = 0;
if (lr == 0)
{
lmotor = readEE(address2);
lr = 1;
}else
{
rmotor = readEE(address2);
lr=0;
}//endif
address2++;
}//end readmotors
you can alias lmotor and rmotor like this: Code:
#define lmotor pwm01 #define rmotor pwm02 you call storemotors() so long as a certain button, like p1_sw_top, is pushed. That way, as long as the button is pushed, you're recording the data you send to the motors. call storemotors() only once you're done processing data and are ready to send it to the pwms. like this: Code:
if (writebutton && (address <= 1023)) {storemotors();}
//stores data in EEPROM for recall in auto mode
like this: Code:
if (address2 <= 1023) {readmotors();} //reads data from EEPROM to motors
else {lmotor = rmotor = 127;}
This is a really simplified version. It can only record one autonomous mode. The 1023 bytes of space should definitely allow you fifteen seconds of recording time. If not, you can always call storemotors and readmotors every other loop. My goal here is to help you understand copycat, not to provide you with the most function. this code has not been tested on the new compiler, so if there's a big problem please tell me. Please post if you have questions! If you have better versions of copycat please share, and explain too! |
|
#2
|
||||
|
||||
|
Re: Copy Cat
Heh, its interesting to see where my CopyCat project has gone over the years
![]() I'm glad that people are still trying to keep it alive! Combined with the PID this year it could be pretty effective... ![]() |
|
#3
|
|||
|
|||
|
Re: Copy Cat
Do storemotors() and readmotors() execute once every long long loop (26.2 ms) or every short loop? I'm still a bit confused to those and it would seem like and awful waste of space to do it more than every 26.2ms.
But either way, does this ever have ideas brewing in my head. ![]() EDIT: misunderstanding about the loops, got it all sorted out now. Last edited by ConKbot of Doom : 28-01-2005 at 15:16. |
|
#4
|
||||
|
||||
|
Re: Copy Cat
Quote:
Either way. so long as it's the same for both. I do it every long loop because that's when you have new data. readmotors is in _fast because that's where use_autonomous_mode is. |
|
#5
|
||||
|
||||
|
Re: Copy Cat
Quote:
It works really well as a backup because it's so simple. I programmed this in an hour while watching Austin Powers. If you have a fairly simple (and not precise) autonomous strategy in mind. |
|
#6
|
|||||
|
|||||
|
Re: Copy Cat
Hmmm. I just tried to compile it and I got a bunch of errors.....
Quote:
|
|
#7
|
||||
|
||||
|
Re: Copy Cat
Quote:
|
|
#8
|
|||||
|
|||||
|
Re: Copy Cat
AHA! You found the problem! I left adress as adress. I take it I am supposed to either change it or declare it as a variable?
|
|
#9
|
|||||
|
|||||
|
Re: Copy Cat
Quote:
Quote:
FWIW, the lines should probably be something like: Code:
unsigned short address; // In user_routines.c and unsigned short address2; // In user_routines_fast.c Code:
unsigned short address = 0; // In user_routines.c and unsigned short address2 = 0; // In user_routines_fast.c Code:
static unsigned short address = 0; // In user_routines.c and static unsigned short address2 = 0; // In user_routines_fast.c Code:
void storemotors(void)
{
static unsigned short address = 0;
static char lr = 0;
if (lr==0) //alternate writing lmotor & rmotor
etc.
}//end storemotors
|
|
#10
|
||||
|
||||
|
Re: Copy Cat
Our programmer figured the out copy cat program last year, but due to his hard work he doesn't want me to share. From what I have seen some of you pretty close. Good luck to everyone trying and happy programming!
GO 1403!!! |
|
#11
|
||||
|
||||
|
Re: Copy Cat
THIS IS NOT MEANT TO BE COMPLETE CODE!!
of course you have to define these variables. you also have to prototype these functions, but I'm not your team's programmer, so I'm going to let you figure that part out. Thanks, though, for pointing out where my code has holes. I didn't actually use copycat this year, so I did not compile an actual working version. Last edited by Meandmyself : 06-03-2005 at 17:09. |
|
#12
|
|||
|
|||
|
Re: Copy Cat
Hey,
After spending months on a PID control without a lot of success, i believe we will have to develop Copy Cat as a backup. Since we are a newbie team we have no experience with this at all so I would request to know the ins and outs of these controls, and the things to keep in mind before using it. Is it controlled using a joystick when its getting recorded? and How many motors does it record, meaning will it record the movements of the arm or only the mobility? Having less than a week to get this to work we are in a state of urgency, any assistance is highly appreciated. Thanks. |
|
#13
|
||||
|
||||
|
Re: Copy Cat
Quote:
while recording, it's controlled in the same way you control it while driving. The way you record is to call the function storemotors while you are actually driving the bot. you don't want to call it all the time, though, because every time you call it it messes up whatever you've already got recorded. Quote:
Quote:
You can record as many motors as you want. You just have to watch out because the more motor values you want to record simultaneously, the less accurate your playback will be. There's a simple way to get around this. Let me illustrate: Suppose I want to control the motion of an arm moving up and down, and suppose I am controlling said arm with a PWM, however the only values I ever send to this arm are 0,127, and 254. I can do this two ways: 1) every third loop I record the value I'm sending to the arm. This is interspersed with the recording of the left and right motors, so that the left motor is stored every third loop and the right motor is stored every third loop. Code:
void storemotors(void)
{
static char lr = 0;
switch (lr) //alternate writing lmotor & rmotor
case 0:
{
writeEE(address, lmotor); //writes the motor value to EEPROM
lr=1; break;
}
case 1:
{
writeEE(address, rmotor);
lr=2; break;
}
case 2:
{
writeEE(address, armmotor); //writes arm motor value to EEPROM
lr = 0; break;
}
address++; //increments address
}//end storemotors
2)since the PWM value 255 is never sent to the motors, you can use 255 as a marker to tell the autonomous mode, "Hey! Arm going up now!" you would also need another unused pwm value to tell the autonomous that the arm is going down. When my team wrote our drive code, we had a little "dead zone" in the middle of the joystick's range, so that if the joystick was in between 117 and 137 the motor was set to 127. this gave us a whole bunch of unused pwm values. Code:
void storemotors(void)
{
static char lr = 0;
static char armupordown = 0;
if(armmotor== 254 && armupordown != 1) //if the arm is going up and the arm wasn't going up last loop
{
writeEE(address, unused pwm value 1); //stores motor going up marker
armupordown = 1; //the arm just started going up
}else if(armmotor == 127 && armupordown != 0) //if the arm has stopped moving and has just this loop stopped moving
{
writeEE(address, unused pwm value 2); //motor stopped marker
armupordown = 0;
}else if (armmotor == 0 && armupordown != -1) //if arm just this loop started going down
{
writeEE(address, unused pwm value 3); // motor going down marker
armupordown= -1;
}else if (lr==0) //alternate writing lmotor & rmotor
{
writeEE(address, lmotor); //writes the motor value to EEPROM
lr=1;
}else
{
writeEE(address, rmotor);
lr=0;
}//endif
address++; //increments address
}//end storemotors
Hope this helps. Ask as many questions as you like. |
|
#14
|
|||
|
|||
|
Re: Copy Cat
Thank you very much for this valuable information, this makes it clearer.
Another, question, do the recorded values remain on the memory after the robot has been switched ON/OFF or Robot Reset is used, meaning is the same record of joystick control on the EEPROM repeatable from game to game or do we have to record every time we want to run autonomous? Thanks again for sharing your expertise on the topic, Vick. |
|
#15
|
||||
|
||||
|
Re: Copy Cat
Quote:
The recorded memory remains in EEPROM even after you switch the robot off. It wouldn't be very useful if it was erased every time you turned the robot on, would it? Watch out, though, because every time you download new code to the RC it erases any stored EEPROM memory, including your recorded autonomous!!! Be very careful about making changes to your code if you don't have time to re-record your autonomous. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Battlebots I.Q.- A serious threat to FIRST or a half thought up cheep copy? | Joe Matt | General Forum | 75 | 17-10-2005 20:43 |
| TEACHERS, Get a free copy of Mac OS 10.2 | MattK | Chit-Chat | 26 | 07-03-2005 18:01 |
| Program to copy list of files from Windows explorer as text into an application? | Elgin Clock | IT / Communications | 6 | 30-12-2004 21:23 |
| Science jokes..... | Adam Y. | Chit-Chat | 20 | 10-12-2004 11:55 |
| 'Aluminum Angle/box/tube'-- copy of posting in General | archiver | 2000 | 0 | 24-06-2002 00:11 |