Go to Post Unconventional isn't necessarily innovation. - AdamHeard [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 27-01-2005, 21:35
Meandmyself's Avatar
Meandmyself Meandmyself is offline
Registered Magic Programming User
AKA: Gordon
#1123 (AIM robotics Crimson Lightning)
Team Role: Programmer
 
Join Date: Jan 2004
Rookie Year: 2003
Location: springfield, VA
Posts: 26
Meandmyself will become famous soon enough
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;
}
put this in your user_routines_fast()
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
address and address2 are unsigned shorts defined in user_routines.c and _fast.c respectively. lmotor is the pwm you used for your left motor and rmotor is the address you used for your right motor.
you can alias lmotor and rmotor like this:
Code:
#define lmotor pwm01
#define rmotor pwm02
that should save you some cutting and pasting.

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
you call readmotors() in user_autonomous_code(). It reads out data from the EEPROM directly into the motors.
like this:
Code:
if (address2 <= 1023) {readmotors();}		//reads data from EEPROM to motors
else {lmotor = rmotor = 127;}
that's it. simple. The only problem you might run into is that it takes a while to write to the EEPROM. If you try to write two bits of data right after the other, it won't write the second bit. This is why I only write one motor per cycle. It definitely took me a while to figure that one out.

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!
__________________
They call me the Idea man.
Not because my ideas work,
But because I have ideas...


I'm not a programmer. I'm an electrical guy who can program. If only I understood C!

www.aim-robotics.org //team website
www.tjhsst.edu/~gburgett //cool stuff for school
  #2   Spotlight this post!  
Unread 27-01-2005, 22:34
Sachiel7's Avatar
Sachiel7 Sachiel7 is offline
<Yes I managed to flip it
AKA: Shayne Helms
FRC #1132 (RAPTAR Robotics)
 
Join Date: Sep 2002
Rookie Year: 2002
Location: Richmond, VA
Posts: 541
Sachiel7 is just really niceSachiel7 is just really niceSachiel7 is just really niceSachiel7 is just really niceSachiel7 is just really nice
Send a message via AIM to Sachiel7
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...
__________________
-=Sachiel7=-

There's no such thing as being too simple!
Look for Team #1132, RAPTAR Robotics at the VCU Regional this year!
  #3   Spotlight this post!  
Unread 28-01-2005, 09:02
ConKbot of Doom ConKbot of Doom is offline
Team Alumni
FRC #1184 (Cobra Robotics)
Team Role: Leadership
 
Join Date: Jan 2005
Rookie Year: 2004
Location: Maryland
Posts: 153
ConKbot of Doom has a spectacular aura aboutConKbot of Doom has a spectacular aura aboutConKbot of Doom has a spectacular aura about
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   Spotlight this post!  
Unread 28-01-2005, 12:35
Meandmyself's Avatar
Meandmyself Meandmyself is offline
Registered Magic Programming User
AKA: Gordon
#1123 (AIM robotics Crimson Lightning)
Team Role: Programmer
 
Join Date: Jan 2004
Rookie Year: 2003
Location: springfield, VA
Posts: 26
Meandmyself will become famous soon enough
Re: Copy Cat

Quote:
Originally Posted by ConKbot of Doom
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.

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.
__________________
They call me the Idea man.
Not because my ideas work,
But because I have ideas...


I'm not a programmer. I'm an electrical guy who can program. If only I understood C!

www.aim-robotics.org //team website
www.tjhsst.edu/~gburgett //cool stuff for school
  #5   Spotlight this post!  
Unread 28-01-2005, 12:39
Meandmyself's Avatar
Meandmyself Meandmyself is offline
Registered Magic Programming User
AKA: Gordon
#1123 (AIM robotics Crimson Lightning)
Team Role: Programmer
 
Join Date: Jan 2004
Rookie Year: 2003
Location: springfield, VA
Posts: 26
Meandmyself will become famous soon enough
Re: Copy Cat

Quote:
Originally Posted by Sachiel7
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...

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.
__________________
They call me the Idea man.
Not because my ideas work,
But because I have ideas...


I'm not a programmer. I'm an electrical guy who can program. If only I understood C!

www.aim-robotics.org //team website
www.tjhsst.edu/~gburgett //cool stuff for school
  #6   Spotlight this post!  
Unread 08-02-2005, 02:30
russell's Avatar
russell russell is offline
Registered User
#1430 (WRONG)
Team Role: Electrical
 
Join Date: Feb 2004
Rookie Year: 2004
Location: Anchorage AK
Posts: 402
russell is a name known to allrussell is a name known to allrussell is a name known to allrussell is a name known to allrussell is a name known to allrussell is a name known to all
Re: Copy Cat

Hmmm. I just tried to compile it and I got a bunch of errors.....

Quote:
Originally Posted by MPLAB
D:\Code\Copy Cat v1\user_routines.c:116:Error [1105] symbol 'address' has not been defined
D:\Code\Copy Cat v1\user_routines.c:116:Warning [2058] call of function without prototype
D:\Code\Copy Cat v1\user_routines.c:120:Error [1105] symbol 'address' has not been defined
D:\Code\Copy Cat v1\user_routines.c:120:Warning [2058] call of function without prototype
D:\Code\Copy Cat v1\user_routines.c:123:Error [1105] symbol 'address' has not been defined
D:\Code\Copy Cat v1\user_routines.c:123:Error [1101] lvalue required
D:\Code\Copy Cat v1\user_routines.c:146:Error [1109] type mismatch in redeclaration of 'writeEE'
D:\Code\Copy Cat v1\user_routines.c:311:Error [1105] symbol 'address' has not been defined
what does that mean?
  #7   Spotlight this post!  
Unread 08-02-2005, 03:15
Unsung FIRST Hero
Mike Betts Mike Betts is offline
Electrical Engineer
no team
Team Role: Engineer
 
Join Date: Dec 2001
Rookie Year: 1995
Location: Homosassa, FL
Posts: 1,442
Mike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond repute
Re: Copy Cat

Quote:
Originally Posted by russell
...what does that mean?
Please show your variable declaration for "address" and I'll be able to tell you what the problem is.
__________________
Mike Betts

Alumnus, Team 3518, Panthrobots, 2011
Alumnus, Team 177, Bobcat Robotics, 1995 - 2010
LRI, Connecticut Regional, 2007-2010
LRI, WPI Regional, 2009 - 2010
RI, South Florida Regional, 2012 - 2013

As easy as 355/113...
  #8   Spotlight this post!  
Unread 08-02-2005, 11:03
russell's Avatar
russell russell is offline
Registered User
#1430 (WRONG)
Team Role: Electrical
 
Join Date: Feb 2004
Rookie Year: 2004
Location: Anchorage AK
Posts: 402
russell is a name known to allrussell is a name known to allrussell is a name known to allrussell is a name known to allrussell is a name known to allrussell is a name known to all
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   Spotlight this post!  
Unread 08-02-2005, 11:06
Greg Ross's Avatar
Greg Ross Greg Ross is offline
Grammar Curmudgeon
AKA: gwross
FRC #0330 (Beach 'Bots)
Team Role: Mentor
 
Join Date: Jun 2001
Rookie Year: 1998
Location: Hermosa Beach, CA
Posts: 2,245
Greg Ross has a reputation beyond reputeGreg Ross has a reputation beyond reputeGreg Ross has a reputation beyond reputeGreg Ross has a reputation beyond reputeGreg Ross has a reputation beyond reputeGreg Ross has a reputation beyond reputeGreg Ross has a reputation beyond reputeGreg Ross has a reputation beyond reputeGreg Ross has a reputation beyond reputeGreg Ross has a reputation beyond reputeGreg Ross has a reputation beyond repute
Send a message via AIM to Greg Ross Send a message via Yahoo to Greg Ross
Re: Copy Cat

Quote:
Originally Posted by russell
Hmmm. I just tried to compile it and I got a bunch of errors.....


what does that mean?
It looks like you didn't follow ALL the instructions:
Quote:
Originally Posted by Meandmyself
address and address2 are unsigned shorts defined in user_routines.c and _fast.c respectively.
Try reading the whole post carefully.

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
Actually, since I didn't see anywhere in the code snippets where the address variables are initialized, that should be:
Code:
unsigned short address = 0; // In user_routines.c
	and
unsigned short address2 = 0; // In user_routines_fast.c
And assuming that these variables don't need to be used outside of these modules, I would make them:
Code:
static unsigned short address = 0; // In user_routines.c
	and
static unsigned short address2 = 0; // In user_routines_fast.c
Further, it looks to me like these address variables aren't needed outside of the storemotors and readmotors functions so, IMHO, these variable declarations should be moved inside their respective functions. E.g.:
Code:
void storemotors(void)
{
	static unsigned short address = 0;
	static char lr = 0;

	if (lr==0)			//alternate writing lmotor & rmotor
	etc.
}//end storemotors
__________________
Greg Ross (The Grammar Curmudgeon formerly known as gwross)
S/W Engineer, Team 330, the Beach 'Bots
<--The Grammar Curmudgeon loves this cartoon.
“Life should not be a journey to the grave with the intention of arriving safely in a pretty and well preserved body, but rather to skid in broadside in a cloud of smoke, thoroughly used up, totally worn out, and loudly proclaiming "Wow! What a Ride!" Hunter S. Thompson
"Playing a practical joke means doing something mean and calling it funny." Me
  #10   Spotlight this post!  
Unread 08-02-2005, 12:20
slickguy2007 slickguy2007 is offline
Copioli is the man!!!
FRC #1403 (Cougar Robotics)
Team Role: Alumni
 
Join Date: Nov 2004
Rookie Year: 1997
Location: Skillman, NJ
Posts: 545
slickguy2007 has a reputation beyond reputeslickguy2007 has a reputation beyond reputeslickguy2007 has a reputation beyond reputeslickguy2007 has a reputation beyond reputeslickguy2007 has a reputation beyond reputeslickguy2007 has a reputation beyond reputeslickguy2007 has a reputation beyond reputeslickguy2007 has a reputation beyond reputeslickguy2007 has a reputation beyond reputeslickguy2007 has a reputation beyond reputeslickguy2007 has a reputation beyond repute
Send a message via AIM to slickguy2007
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   Spotlight this post!  
Unread 06-03-2005, 17:05
Meandmyself's Avatar
Meandmyself Meandmyself is offline
Registered Magic Programming User
AKA: Gordon
#1123 (AIM robotics Crimson Lightning)
Team Role: Programmer
 
Join Date: Jan 2004
Rookie Year: 2003
Location: springfield, VA
Posts: 26
Meandmyself will become famous soon enough
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.
__________________
They call me the Idea man.
Not because my ideas work,
But because I have ideas...


I'm not a programmer. I'm an electrical guy who can program. If only I understood C!

www.aim-robotics.org //team website
www.tjhsst.edu/~gburgett //cool stuff for school

Last edited by Meandmyself : 06-03-2005 at 17:09.
  #12   Spotlight this post!  
Unread 12-03-2005, 00:16
thinkpad thinkpad is offline
Registered User
AKA: Mr. Know Nothing
no team
Team Role: Programmer
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Canada
Posts: 15
thinkpad is an unknown quantity at this point
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   Spotlight this post!  
Unread 12-03-2005, 13:13
Meandmyself's Avatar
Meandmyself Meandmyself is offline
Registered Magic Programming User
AKA: Gordon
#1123 (AIM robotics Crimson Lightning)
Team Role: Programmer
 
Join Date: Jan 2004
Rookie Year: 2003
Location: springfield, VA
Posts: 26
Meandmyself will become famous soon enough
Re: Copy Cat

Quote:
Originally Posted by thinkpad
Hey,

Is it controlled using a joystick when its getting recorded?

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:
Originally Posted by Meandmyself
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.
Quote:
Originally Posted by thinkpad
and How many motors does it record, meaning will it record the movements of the arm or only the mobility?

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
and you do the same sort of thing in Readmotors to get the values out.

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
and then of course somthing similar in readmotors to recognize the markers.

Hope this helps. Ask as many questions as you like.
__________________
They call me the Idea man.
Not because my ideas work,
But because I have ideas...


I'm not a programmer. I'm an electrical guy who can program. If only I understood C!

www.aim-robotics.org //team website
www.tjhsst.edu/~gburgett //cool stuff for school
  #14   Spotlight this post!  
Unread 12-03-2005, 20:19
thinkpad thinkpad is offline
Registered User
AKA: Mr. Know Nothing
no team
Team Role: Programmer
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Canada
Posts: 15
thinkpad is an unknown quantity at this point
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   Spotlight this post!  
Unread 13-03-2005, 12:09
Meandmyself's Avatar
Meandmyself Meandmyself is offline
Registered Magic Programming User
AKA: Gordon
#1123 (AIM robotics Crimson Lightning)
Team Role: Programmer
 
Join Date: Jan 2004
Rookie Year: 2003
Location: springfield, VA
Posts: 26
Meandmyself will become famous soon enough
Re: Copy Cat

Quote:
Originally Posted by thinkpad
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.

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.
__________________
They call me the Idea man.
Not because my ideas work,
But because I have ideas...


I'm not a programmer. I'm an electrical guy who can program. If only I understood C!

www.aim-robotics.org //team website
www.tjhsst.edu/~gburgett //cool stuff for school
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

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


All times are GMT -5. The time now is 22:02.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi