Path-Remebering Bot..

Status
Not open for further replies.

Electrix

Member
A robot is manually (thru RF remote control) guided along a path. The bot should memorize this exact sequence of left-right turns of specific durations...and then upon user command...execute the same path over again, autonomously.

How do i make my bot remeber the sequence for a specified time..
The sequence is like .. 'XXXX01010' for right... and if this is for 5 sec... then storing the sequence is not a prob.. but how do i manage the timing..
I'm using the PIC16F73..
Would appreciate any help on this.
 
i suggest puting a rotation sensor on both (all) wheels and connecting them to a AVR/PIC. the pic must be different from the one used for RF communications (if it is being used). then you just simply read the pulses you get from the wheels, store them into EEPROM memory bank from time to time (after every turn) and then jujt simply read the values back when you need to remake that path again. it isnt that hard to do actually if you can follow my flight of thought (as we say here in estonia).
 
That reminds me of the industrial welding robot I saw about 10 years ago, where you'd just grab its "hand" and push it through whatever motion path you wanted (which it would then repeat).

All it really has to do is sample its states in program mode, and cycle through those states in run mode. It doesn't matter if you get 100 samples in a row of "moving forward at X velocity", as long as you have enough RAM. Should memory be a problem, I might suggest run length encoding.
 
yes this is the place it is mainly used. but it can also be used for such tasks as Electrix wants to make. only problem is, that the environbent has to be exactly the same for it to work properly. thats why i build autonomus robots that are able to think also not just go on a path that has given it. it's much more fun...
 
The way this sort of data is normally stored is using Run Length Encoding (google RLE). Every command is stored as 2 bytes, a direction and a distance.
As you are using a Pic that does not have EEPROM, you have to store your data in ram. I would suggest using the 96 bytes in page 1. As you only need 4 bits for your direction data, then you could use 12 bits for distance. So each byte pair would contain LRFBdddd dddddddd. For, Left, Right, Forward and Back and the distance (or time) could be up to 4096 counts. If you settle for a resolution of 100th of a second, then your time count could be over 40 seconds.
For example,
0010 0000 1100 0100 = move forward for 1 second.
1000 0000 0001 1011 = turn left for 0.27 seconds.
Etc.

This would give you 48 commands that could be recorded. I’m not sure how good the repeatability would be with just time. As has previously been mentioned, counting pulses from the wheels would be much more accurate.

As for generating the 100th of a second time base, the simplest way is to use the Special Event Trigger of CCP1. You initialise it like this,
Code:
                movlw   B'00001011'
                movwf   T1CON;		enable timer 1
                movlw   low(50000)
                movwf   CCPR1L
                movlw   high(50000)
                movwf   CCPR1H
                movlw   B'00001011';	enable special event trigger on CCP1
                movwf   CCP1CON;

The 50,000 in the above code is the crystal frequency/4/100. 50,000 is for a 20MHz crystal, for a 4MHz crystal it would be 10,000.
You can test for time up in one of two ways,
By Polling. CCP1IF will be set every 100th of a second. You can test it by
Code:
WaitTimeUp      btfss   PIR1,CCP1IF
                goto    WaitTimeUp
                bcf     PIR1,CCP1IF
Or you can enable interrupts
Code:
                bsf     STATUS,RP0
                bsf     PIE1,CCP1IE;	enable CCP1 interupt
                bcf     STATUS,RP0
                movlw   B'11000000'
                movwf   INTCON;		enable Peripheral interupts
And have an interrupt handler.

HTH

Mike.
 
Thanks guys .. those were really helpful suggestions.. i'm gonna try the 'fixed time intervals' sampling method.. and test for accuracy..and then would consider using the Rotational Sensor..

Hey Mike.. thanks for that fantastic explaination !

.. will work it out and let u guys know.
 

Hey Mike.. i'm a bit confused.. after generating the 100th of a second time base.. how do you record the time.. i mean say 1010 is for 1 sec.. how do i know this without the rotational sensor (i'm sorry i dont know whether ur advice is with using a rotat sensor) . One way i thought was by using the RB4-RB7 change on pin interrupts and then recording time.. is this what you had in mind ?
 
Dan East said:
When I hear RLE I think of it as a lossless compression algorithm.

Dan East

And when I hear East I think of it as a direction on a compass!

Your point?

Mike.

Electrix, I'll try and explain tomorrow.
 
Pommie said:
And when I hear East I think of it as a direction on a compass!

Your point?

That googling for RLE will tell him everything he needs to know about implementing RLE image compression, which I don't think will help him with his current project. So either RLE can be used in an obscure way to describe the algorithm you're talking about, or you are mistaken in referring to it as RLE in the first place.

Dan East
 

He's referring to RLE (Run Length Encoding), as a method of storing the path in comressed form - EXACTLY as it's used in image compression.

For example, if you have a line of 50 pixels that are blue, you don't store it as 50 blue pixels, you store it as 50blue - which only takes two bytes (one for the number, and one for the colour).

This works just the same for the path, you don't store 50 steps forward, you simply store 50forward - only two bytes again.

Generally RLE has a maximum of 255, so for 300 boluse pixels you would store 255blue, 45blue - taking four bytes.

Incidently, the Commodore Amiga used RLE in its graphic format, which is where I came across it!.
 
I think you need a history lesson. The first time I came across the term RLE was in the mid 80's. It referred to a hard disk drive that used RLE encoding. How anyone managed to claim GIF as original is beyond me.

BTW, if what I described is not RLE, then what is RLE?

Mike.
 
Pommie said:
BTW, if what I described is not RLE, then what is RLE?

Okay, I see what you're getting at. You're considering "button a is pressed for 500 ms" as RLE, instead of as a sequence of states at some sample rate. To me you were simply describing an event driven system, which is why I did not relate it to RLE.

Dan East
 

If your remote control is 4 push buttons on RB4-7 then, after a reset, you would wait for a non zero value to indicate a button has been pressed. You would then start to count 100th by checking the PIR1,CCP1IF. You carry on checking the buttons and counting until either the buttons change or you reach a count of 4095 (1111 1111 1111). You then store the Button state and the count into memory and start again with the new buttons value. Carry on until the memory is full.

Mike.
 

Thanks, that clears everything. Will try this out.
 
Code:
 movlw   B'00001011' 
                movwf   T1CON;      enable timer 1 
                movlw   low(10000) 
                movwf   CCPR1L 
                movlw   high(10000) 
                movwf   CCPR1H 
                movlw   B'00001011';   enable special event trigger on CCP1 
                movwf   CCP1CON;

This is the code as Mike suggested for the initialization of CCP1 module for special event trigger. (Note that for 10msec interrupt, using a 4MHz crystal the value works out to be 10000 )
Now while assembling I get a message:

Operand of HIGH operator was larger than H'FFFF'

Please explain the meaning of this as 10000 in dec is equal to 2710 in hex.... also help me solve this problem.

Thanks
 
Electrix said:
Please explain the meaning of this as 10000 in dec is equal to 2710 in hex.... also help me solve this problem.
Thanks

What about 10000 in HEX? Does the assembler knows that 10000 is decimal?

Have you used the "R=DEC" option in the assembler list directive?
 
Yup..thats the problem ! the 'radix dec' command was missing.

Thanks


 
This is the code that was suggested by Mike.. but I'm facing a problem.. there is no interrpt taking place whenever there is a match between CCP1L..CCP1H & Timer1 (L & H).. I've run the code on the simulator.. and there is no flag being set for CCP1F .. I'm using the pollong method to check for the event trigger...Please Help...

Code:
                movlw   B'00001011'
                movwf   T1CON;		enable timer 1
                movlw   low(50000)
                movwf   CCPR1L
                movlw   high(50000)
                movwf   CCPR1H
                movlw   B'00001011';	enable special event trigger on CCP1
                movwf   CCP1CON;

Code:
WaitTimeUp      btfss   PIR1,CCP1IF
                goto    WaitTimeUp
                bcf     PIR1,CCP1IF
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…