Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   EDU Mini Controller & 2005 Nav Code (http://www.chiefdelphi.com/forums/showthread.php?t=40352)

jaustin 06-11-2005 15:54

EDU Mini Controller & 2005 Nav Code
 
I'm attempting to implement Kevin Watson's 2005 Nav code on our EDU Mini controller to give my team a small scale platform to learn about PID contollers and to expirement with their own code. (this will be the first year we attempt to use encoders & gyros) I basically took the EDU code as written and added pid.c/h, robot.c/h, encoder.c/h, gyro.c/h, commands.h as well as adc.c/h. I updated the ISR's for adc & encoder.c. I have also updated all the constants to apply to the smaller bot. The software compiles and runs but I'm having a few problems.

1) I put CMD_GYRO_BIAS at the top of the list and it seems to work fine. However, it seems to go haywire after that. Sometimes it steps through my command list just fine and other times it jumps out of the loop to show "unknown command restarting ...". It's as if the rc variable is getting randomly set, and when it moves to the next command it does not recognize it (even thought it did the last time it ran). I've got the NULL command as the last one.

2) The PID algorythm does not really monitor the error between the left and right motor speeds and so the bot won't go straight. This is a known shortcomming and I've read all the posts and some friendly folks are helping with code examples to fix that. However, I can't even get the bot to go straight when contolling on velocity. No mater what setting (pwm value) I use, my left motors alway go faster than my right motors. I'm wondering if there is some inherant issue with either the EDU mini controller or the motors?

Any advice would be appreciated! Thanks folks!

Jeff Austin
Mentor - Team 372

Mark McLeod 06-11-2005 18:38

Re: EDU Mini Controller & 2005 Nav Code
 
Quote:

Originally Posted by jaustin
It's as if the rc variable is getting randomly set, and when it moves to the next command it does not recognize it (even thought it did the last time it ran).

Possibly a memory overwrite. You might generate a .map file and check it to see where your arrays are falling relative to the memory location of rc (i.e., those at lower addresses can overwrite higher addresses), and print the values of rc to see if it's really random. Make sure rc is static or global.

For the unbalance power of the left vs. right drive I'd test both at max pwm (forward and backward) and then begin slowing the faster side until the sides are balanced. That'll give you a more concrete measurement of the magnitude of the problem. The motors, chain, wheels all contribute to mismatched power, but it's not usually so severe. This is actually one of the exercises I put the new programmers through, by purposely unbalancing things (through s/w or mechanics) and having them rebalance in software.
P.S. The difference is usually proportional or close to it, so you can apply a percentage of the max correction at slower pwms.

Pat Fairbank 06-11-2005 21:21

Re: EDU Mini Controller & 2005 Nav Code
 
Quote:

Originally Posted by jaustin
I'm wondering if there is some inherant issue with either the EDU mini controller or the motors?

I still own and use one of the old Robovation kits, and I've observed that there is in fact a HUGE difference in the forward and reverse speeds of the motors. If this is what is causing the problem in your case, when you run the robot backwards the right motors should now rotate faster than the left motors. I think I've had to cut back on the speed of one motor by as much as one half to compensate.

The PID loop in the navigation code probably isn't designed in a way that would allow it to compensate for this much a speed difference (between the expected and actual speeds for forward and reverse), so your best bet is to follow Mark's procedure and slow down the motors for the appropriate direction of rotation in the code, after having run the PID loop.

jaustin 07-11-2005 02:05

Re: EDU Mini Controller & 2005 Nav Code
 
Yes you are both (Pat & Mark) correct relative to the speed differences of the EDU motors in fwd & rev. I have been able to slow the one side down in the code to allow it to track fairly straight. I just added a 60/100 factor at the end of the PID routine to the right sides pwm value and it works ok now.

Mark,
On the other problem I too suspect some kind of memory over-write or over-flow problem. I printed out the rc values and they show up as either 1 or 0 99.9% of the time. But occasionally a random 485 or 2046 shows up and then things go south. I'm kind of a novice with the PIC and C. I not familiar with how to create a .map file to check my memory allocations. Is there a website that explains how to do it? Should I use the "extern int" identifier for rc to ensure it's a global variable somewhere outside the robot_command() function? (if that's it, I'm curious why Kevin did not do it that way to start with).

Thanks guys for all your help!

Jeff

Mark McLeod 07-11-2005 08:02

Re: EDU Mini Controller & 2005 Nav Code
 
The memory map can be generated by MPLAB whenever you compile your code by going to:
Project -> Build Options... -> Project
then click on the "MPLINK Linker" tab,
then click on "Generate map file".
After you build your project look in your project directory for a text file ending in ".map". You can view it in any text editor.

The *.map file has four parts:
1) Section Info
2) Program Memory Usage
3) Symbols - Sorted by Name
4) Symbols - Sorted by Address

Section 2 is pretty useful as it gives the utilization summary for the Program Space directly, but 90% actually represents full as far as the user is concerned.

Section 4 shows the Data Space utilization that you want (ignore for now the Program Space – see column marked “location”). It provides the starting address of each declared variable. The ending address can be either assumed to be where the next variable starts or calculated from the known size.

-----------------
rc is fine declared the way it is. My fault for snapping off a quick afterthought and not checking the code first.
rc's value is the status returned from each of the driving functions, so the problem is probably within one or more of the driving functions.
Identify the function(s) being executed when it returns the bad values. It could be as simple as just not being assigned before exiting the drive routine.

If it's an overwrite issue it'll either be within the drive function or possibly with any debug printfs that occur before you check rc to proceed to the next command.

As regards the printf, the EDU code because of it's age is probably not using the newest C compiler version, but an old IFI version printf_lib.c/h. That old version has several limitations you should read about in the printf_lib.c header comments. I only mention it because one of the limitations is it will overwrite if you attempt to printf a long message (> 80 characters). I doubt this is your problem because the bad rc numbers you quoted are not the ASCII characters you'd expect if this were happening.

Kevin Watson 07-11-2005 11:22

Re: EDU Mini Controller & 2005 Nav Code
 
Quote:

Originally Posted by jaustin
...The software compiles and runs but I'm having a few problems...

How many encoder ticks per second are you generating and how fast is the ADC sampling the gyro?

-Kevin

jaustin 08-11-2005 02:13

Re: EDU Mini Controller & 2005 Nav Code
 
Mark/Kevin,
I've been sent out on a business trip. I won't be back til later this week so please stay tuned!

Mark,
Thanks for the .map info, I'll give it try.

Kevin,
ACD sampling - I have been trying it at 200, 400 and 800 HZ. It does not seem to matter.

Ticks/sec - I'll have to confirm the numbers when I get home but I'm using the 128 Grayhill 61K encoder. At ~500mm/sec with 60 mm dia wheels and a 1 to 1 ratio between the encoder gear and the wheel gear, it's about 340 ticks/sec I'm guessing.

Mike Bortfeldt 08-11-2005 16:35

Re: EDU Mini Controller & 2005 Nav Code
 
Another possibility since you are using ISRs is that a compiler generated temporary variable (or MATH variable) being used by your main code is being overwritten during the execution of the ISR. If this is happening, then your code can behave very unpredictably. As a quick check, look just before the "void InterruptHandlerLow ()" routine in the user_routines_fast.c file, there should be a line similar to the following:

#pragma interruptlow InterruptHandlerLow save=PROD, section(".tmpdata"), section("MATH_DATA")

At a minimum, the PROD & ".tmpdata" section should be in the #pragma statement. While Kevin's code contains both of these, the default EDU code does not. The MATH_DATA section is probably not needed but for testing purposes it won't hurt to add it just in case (except for some additional latency executing the interrupts). Kevin's code usually includes multiple versions of this line, so you may be able to just uncomment the correct one. This may not help, but I thought it was at least worth a mention.

Mike

jaustin 13-11-2005 18:53

Re: EDU Mini Controller & 2005 Nav Code
 
Mike Bortfeldt,
This is what was in the position you noted:
#pragma interruptlow InterruptHandlerLow save=PROD /* You may want to save additional symbols. */

I commented that line out and put this line below it:
#pragma interruptlow InterruptHandlerLow save=PROD, section(".tmpdata"), section("MATH_DATA")

The randomness has gone away and the software steps through my command list without jumping around! Thanks for the help!

Now I need to work on the turning. The gyro code does not seem to be working now... stay tuned for more questions!

Mark McLeod 13-11-2005 21:45

Re: EDU Mini Controller & 2005 Nav Code
 
Nice catch.

jaustin 14-11-2005 23:46

Re: EDU Mini Controller & 2005 Nav Code
 
Ok guys, here is my gyro "issue":

Here is an extract from gyro.c (I added all the printf's)
Specifically it is from the Process_Gyro_data() function:

else
{
// get the latest measured gyro rate
temp_gyro_rate = (int)Get_ADC_Result(GYRO_CHANNEL) - gyro_bias;
printf("gyro_bias = %d\n", gyro_bias);
printf("temp_gyro_rate = %d\n", temp_gyro_rate);

// update reported gyro rate and angle only if
// measured gyro rate lies outside the deadband
if(temp_gyro_rate < -GYRO_DEADBAND || temp_gyro_rate > GYRO_DEADBAND)
{
// update the gyro rate
gyro_rate = temp_gyro_rate;
printf("gyro_rate = %d\n", gyro_rate);
// integrate the gyro rate to derive the heading
gyro_angle += (long)temp_gyro_rate;
printf("gyro_angle = %d\n", gyro_angle);
}

Here is some sample output:
gyro_bias = 1944
temp_gyro_rate = -820
gyro_rate = -820
gyro_angle = -1
gyro_bias = 1944
temp_gyro_rate = -788
gyro_rate = -788
gyro_angle = -1
gyro_bias = 1944
temp_gyro_rate = -766
gyro_rate = -766
gyro_angle = -1

I was worried that the gyro was not working or the ADE was not working but they appears to be working fine. All the calculations seem to be working fine until it gets to the "gyro_angle += (long)temp_gyro_rate;" line of code. All that the variable gyro_angle will ever be is -1 or 0. I can move the gyro and get it to change from 0 to -1 and visa versa. Any ideas? I'm guessing my C abilities are getting in the way?

prograid 14-11-2005 23:58

Re: EDU Mini Controller & 2005 Nav Code
 
Quote:

Originally Posted by jaustin
Ok guys, here is my gyro "issue":

...
I was worried that the gyro was not working or the ADE was not working but they appears to be working fine. All the calculations seem to be working fine until it gets to the "gyro_angle += (long)temp_gyro_rate;" line of code. All that the variable gyro_angle will ever be is -1 or 0. I can move the gyro and get it to change from 0 to -1 and visa versa. Any ideas? I'm guessing my C abilities are getting in the way?

I'm not sure about this, but I believe that the EDU controller shares pins for digital and analog inputs. You need to set the input your gyro is plugged into to be an analog input in user_initialization() which is user_routines.c.

Good Luck!

Manoel 15-11-2005 01:00

Re: EDU Mini Controller & 2005 Nav Code
 
Quote:

Originally Posted by prograid
I'm not sure about this, but I believe that the EDU controller shares pins for digital and analog inputs. You need to set the input your gyro is plugged into to be an analog input in user_initialization() which is user_routines.c.

Good Luck!

Considering he gets a valid gyro bias and rate, the problem is not the reading.

jaustin,

gyro_angle is declared as a long in Kevin's code. The comments section of printf_lib.c states that you should use %lx, but I have never tried that.
What will work (and what Kevin's code does in another section) is to type-cast the long variable. You should print it like that:
Code:

temp_gyro_angle = Get_Gyro_Angle();
printf("Gyro Angle=%d\r\r", (int)temp_gyro_angle);

Depending on what compiler version you're using, it should be \r or \n.
Anyway, on your code you're printing three times inside the Process_Gyro_Data function. This is an interrupt service routine, and it should be processed as fast as possible. Printf takes a lot of time, and it is unwise to use it three times (actually, to use it at all) inside an ISR.
Check user_routines.c on Kevin's code, there are some examples that will print exactly what you want without "side effects".

Kevin Watson 15-11-2005 11:49

Re: EDU Mini Controller & 2005 Nav Code
 
Quote:

Originally Posted by jaustin
Ok guys, here is my gyro "issue"...

Have you run the latest gyro code on your controller without any modifications other than setting the gyro type in gyro.h and compiling? If so, did it work? If not, can you give it a try?

-Kevin

Kevin Watson 15-11-2005 19:45

Re: EDU Mini Controller & 2005 Nav Code
 
Quote:

Originally Posted by jaustin
Ok guys, here is my gyro "issue"...

Re-reading your post, I realized that you're reaching deep into the code and looking at half-baked data. The variable gyro_angle is just a summation of all of the preceeding gyro rate measurements and won't make sense until you examine the return value of Get_Gyro_Angle( ). Here's the function:

long Get_Gyro_Angle(void)
{
// Return the calculated gyro angle to the caller.
return(((gyro_angle * GYRO_SENSITIVITY *5L) / (ADC_RANGE * ADC_UPDATE_RATE)) * GYRO_CAL_FACTOR);
}

I only calculate the angle "on demand" to keep the load on the microcontroller to a minimum.

BTW, I've spent quite a bit of time in Mukilteo -- mostly waiting for the ferry to Whidbey Island <grin>.

-Kevin


All times are GMT -5. The time now is 04:33.

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