Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Quick Question (http://www.chiefdelphi.com/forums/showthread.php?t=22582)

Burgabot 05-11-2003 21:57

Quick Question
 
Ok, the documentation of this year's EDU-RC says that the analog inputs are 10-bit rather than 8-bit this year. Therefore, if we were using last year's gyro to practice with, would it return a value between 0 and 1023? If this is the case, would it even return values that aren't multiples of 4 (since last year's resolution was only 255)? Also, are there any obscure two-byte data types in C? It seems like a waste of space to use an int to store this value. Thanks!

Dave Flowerday 05-11-2003 22:23

Re: Quick Question
 
Quote:

Originally posted by Burgabot
Therefore, if we were using last year's gyro to practice with, would it return a value between 0 and 1023? If this is the case, would it even return values that aren't multiples of 4 (since last year's resolution was only 255)?
Yes and yes. The gyro puts out an analog value, so it's resolution is essentially infinite. It's the microcontroller that rounds it off to some finite amount. The old controllers rounded the value to 8 bits, the new one rounds to 10.
Quote:

Also, are there any obscure two-byte data types in C? It seems like a waste of space to use an int to store this value. Thanks!
It's not obscure, really. The keyword is short int. On most compilers this is a 16 bit value. I haven't checked yet with the PIC C compiler if this is the case with it, though.

Burgabot 05-11-2003 22:39

I should have clarified what I meant by "obscure." In my mind, an obscure data type is anything that I don't bother to use when programming on a computer because the RAM is essentially infinite. :)

Dave Flowerday 05-11-2003 22:43

Quote:

Originally posted by Burgabot
I should have clarified what I meant by "obscure." In my mind, an obscure data type is anything that I don't bother to use when programming on a computer because the RAM is essentially infinite. :)
Hmm... I suppose it wouldn't be used much in desktop programming. We use it in embedded software development all the time, especially when you need to interact directly with the hardware.

Burgabot 05-11-2003 23:08

Actually, I do have another question. Originally, I was going to measure angular velocity by integrating angular accleration, obtained from two linear accelerometers placed a certain distance apart. I did this because the gyro can only measure angular velocities of ±75 degrees/second or less, and runs into trouble at anything higher than that. However, I realized that this will be far less accurate than using a gyro sensor.

Basically, what it comes down to is that there's a tradeoff between accuracy (the gyro) and range (the two acclerometers). Therefore, I came up with a compromise that I hope will work. In every program cycle, I'll get the angular speed as determined by the gyro. If it turns out to be 75 degrees/second (which I'm assuming is what it'll return if the speed is higher than that), I'll use the accelerometer data instead of the gyro data to determine the angular velocity. That way, I'll have the accuracy of the gyro at normal speeds and the range of the accelerometer arrangement at high angular speeds. Think this will work? Anything I have to watch out for?

Dave Flowerday 06-11-2003 07:36

Quote:

Originally posted by Burgabot
If it turns out to be 75 degrees/second (which I'm assuming is what it'll return if the speed is higher than that), I'll use the accelerometer data instead of the gyro data to determine the angular velocity. That way, I'll have the accuracy of the gyro at normal speeds and the range of the accelerometer arrangement at high angular speeds. Think this will work? Anything I have to watch out for?
That sounds like it has potential. The biggest problem I see would be caibrating the two so when you switch from using the gyro to the accelerometers you're still integrating the same value. Also you'll need to build in some hysteresis so that if your velocity is right at the point of switching from the gyro to the accelerometors, you don't rapidly toggle back and forth between them. To do this, you would only switch away from the gyro if the velocity is >= 70 deg/sec, but you wouldn't switch back to it until the value fell below 65 deg/sec.

Chris Hibner 06-11-2003 08:03

Use a different "gyro"
 
Quote:

Originally posted by Burgabot
Actually, I do have another question. Originally, I was going to measure angular velocity by integrating angular accleration, obtained from two linear accelerometers placed a certain distance apart. I did this because the gyro can only measure angular velocities of ±75 degrees/second or less, and runs into trouble at anything higher than that. However, I realized that this will be far less accurate than using a gyro sensor.
I would contact Future and buy an Analog Devices angular rate sensor ("gyro"). They have one that can measure +/- 300 degrees/second.

-Chris

Andrew 06-11-2003 09:20

For those of you who have used the gyro on FIRST robots, how much of a limitation is 75 degrees per second? Have you seen your robot exceed that value?

I would think that the errors introduced by scaling the value between 0...255 would introduce more overall error in the integration than the robot turning faster than 75 dps.

It also depends on what you're doing with the gyro. If you're doing odometry, seems like you're going to have errors from wheel slip and integration of gyro which will require an on-the-fly recalibration regardless.

If you're just using the gyro for closed loop control, the 75 dps limit shouldn't make as much difference as the sample rate limitation and the quantization limitation.

seanwitte 06-11-2003 09:27

Re: Use a different "gyro"
 
Quote:

Originally posted by Chris Hibner
I would contact Future and buy an Analog Devices angular rate sensor ("gyro"). They have one that can measure +/- 300 degrees/second.
-Chris

Just a note on that part. There are two models, the ADXRS150 and the ADXRS300. The number corresponds to the max degrees per second. There is an evaluation board available at Future and Arrow that includes all the caps in the sample application in the datasheets. The part number has an -EB appended to it. Those devices are about the size of a pencil eraser and are a ball-grid array so you can't solder them by hand. The EB parts look like a basic stamp and can be pushed into a regular 20 pin IC socket.

Chris Hibner 06-11-2003 11:16

Quote:

Originally posted by Andrew
For those of you who have used the gyro on FIRST robots, how much of a limitation is 75 degrees per second? Have you seen your robot exceed that value?

I would think that the errors introduced by scaling the value between 0...255 would introduce more overall error in the integration than the robot turning faster than 75 dps.

For the first question: Our robot typically turns at around 180 degrees per second. Due to this, the 75 degree/sec GyroChip is pretty much useless to us. If you want to use it for a different application, this limitation might not be a problem. You should also have some margin for unexpected occurances. For instance, our robot can turn at 180 deg/sec on its own, but when we get hit by another robot, it might be able to turn much faster. Therefore, the 300 deg/sec part gives us a little margin.

For the second part: Quantization of the signal (using 256 discrete values instead of infinitely many values of an analog signal) is not that much of a problem, especially if you have enough random noise with peaks above 1 A/D count. This will also be less of a problem with the new PIC micro since it has a 10-bit A/D (1024 discrete values, instead of 256 with the 8-bit A/D).


Random noise at the A/D can improve the apparent resolution of your A/D converter. This could actually be an entire whitepaper. If there is enough interest, I'll try and find time to write it up.

Greg Ross 06-11-2003 13:58

Quote:

Originally posted by Chris Hibner
Random noise at the A/D can improve the apparent resolution of your A/D converter. This could actually be an entire whitepaper. If there is enough interest, I'll try and find time to write it up.
That seems like a counterintuitive statement. I would like to see that white paper.

Burgabot 06-11-2003 16:59

So, you'd recommend that I use last year's gyro for speeds less than 75 degrees/second, one of Future's for speeds greater than 75 and less than 300, and accelerometers for any thing greater than 300?

Chris Hibner 07-11-2003 13:55

Quote:

Originally posted by gwross
That seems like a counterintuitive statement. I would like to see that white paper.
Greg,

I just finished the white paper and submitted it. It will be up soon (once it is approved).

-Chris

Chris Hibner 07-11-2003 14:04

Quote:

Originally posted by Burgabot
So, you'd recommend that I use last year's gyro for speeds less than 75 degrees/second, one of Future's for speeds greater than 75 and less than 300, and accelerometers for any thing greater than 300?
Sorry for two posts in a row...

I would use last year's gyro for speeds less than 50 deg/sec, the 300 deg/sec gryo for less than 200 deg/sec. If you know absolutely, 100% FOR SURE what your worst-case speed is, you can reduce the margin (like use the 75 deg/sec gryo up to 65 deg/sec). Just be sure you account for getting bumped by other robots.

Also, I don't know if I would ever recommend using accelerometers. Our team actually thought of doing this last year (before we found the 300 deg/sec part), but we found a lot of potential problems. We decided that if we had to, we would be better off building an old-fashioned mechanical gyroscope and measuring the gymbal angle with a potentiometer.

If you do go with accelerometers, be sure you select the G-range appropriately. In other words, calculate out how much acceleration they will see in normal usage, then apply a little margin, then buy accelerometers in this range. Most accelerometers you'll find will be like +/- 50 G's. This will give you WAY too little resolution. You'll probably need a low-G accelerometer (like +/- 5 G), which you will pay an arm and a leg for.

-Chris

KevinB 11-11-2003 09:36

Quote:

Originally posted by Chris Hibner
I just finished the white paper and submitted it. It will be up soon (once it is approved).
Excellent White Paper! Thanks for posting it!

Anthony Kesich 11-11-2003 17:04

Re: Re: Quick Question
 
Quote:

The keyword is short int. On most compilers this is a 16 bit value. I haven't checked yet with the PIC C compiler if this is the case with it, though. [/b]
Unless the PIC C compiler is really stange and unlike all others, short int is the same as int is the same as shortthe only thing smaller is char (-128 to 127) and unsigned char (0 to 255).

Random Dude 11-11-2003 20:31

Yes, both the int and short int types are 16 bit. I ran them through sizeof() to confirm it as well.

KevinB 11-11-2003 23:14

I know that int is in fact a 32-bit variable on some systems/compilers, although apparantly not on the PIC.

Dave Flowerday 11-11-2003 23:33

Re: Re: Re: Quick Question
 
Quote:

Originally posted by Anthony Kesich
Unless the PIC C compiler is really stange and unlike all others, short int is the same as int is the same as shortthe only thing smaller is char (-128 to 127) and unsigned char (0 to 255).
I'm not sure what you mean here. On most 32 bit systems (meaning almost all desktops and a large percentage of embedded systems), the compiler will use a 32 bit value for int and a 16 bit value for short int.

The reason that int on the PIC is 16 bits is because it's only a 16 bit system, so it doesn't natively deal with a 32 bit value.

rbayer 11-11-2003 23:44

In C++ (and I assume C as well), variable types are defined as follows:

a) a short is at LEAST 16-bits
b) a long is at LEAST 32-bits
c) an int is no smaller than a short and no bigger than a long

By convention, ints are the same number of bits as the processor you are working with (which is 16 in this case), but that's not a strict requirement.

Random Dude 11-11-2003 23:58

Here is the sizes of all the basic types (If i've forgotten any let me know)

char : 1 byte
short : 2 bytes (this type is the same as short int)
int : 2 bytes
long : 4 bytes (this type is the same as long int)
float : 4 bytes
double : 4 bytes
long double : 4 bytes

These values are from sizeof() so this is the way things are.

Chris Hibner 13-11-2003 09:46

Use typedefs
 
The size of variable types (e.g. int, char, short int, long, etc) can vary for a lot of reasons. It's typically good embedded coding practice to typedef descriptive names for variable types, so type ambiguity is eliminated.

To do this, write a quick program that uses sizeof() to determine the size of all of the built in variable types. Then, use this information to create a file called "type.h" and include it in your code. type.h should look as follows:

/* type.h -- specifies meaningful type definitions */

#ifndef _TYPE_H_
#define _TYPE_H_
/* the above lines guarantee the file isn't included more than once */

typedef unsigned char uint8;
typedef signed char sint8;
typedef unsigned short uint16;
typedef signed short sint16;
typedef unsigned long uint32;
typedef signed long sint32;

/* etc. with whatever types you want to use */


/* end the #ifndef directive */
#endif

/* end of type.h */


Of course, in the above code, you need to use your results from your short "sizeof" program.

After including type.h in your program, NEVER AGAIN use the standard types (i.e. int, short, etc.) Instead, declare everything using your made-up types, so you (and others) know exactly what variable sizes you're using. For example, look at the following code:

int FilterInput; /* from looking at this, no one has any idea how big FilterInput is depending on the micro/compiler combo it could be 16-bit or 32-bit */

sint16 FilterInput; /* everyone (including the programmer) knows exactly that this is a signed 16 bit integer */


The main point is, if you set up your typedefs properly, your code is much more likely to do what you intend it to do. It also has the added benefit that it is more readable others.

-Chris

KenWittlief 13-11-2003 10:24

on the gyro - we used the FIRST yaw rate sensor last year for two functions

one was to close the loop on steering. If you use one joystick, then its very easy to compare the X axis input to the yaw rate of the gyro, and see how fast the bot is turning compared to how fast the driver is commanding it to turn

and close the loop on the difference. This worked extreemly well - esp if you have a bot that is hard to steer - it turns the steering into a servo function

it was also very useful for going up and down the ramp - if the driver is commanding the bot to go straight up the ramp, the yaw rate sensor can detect if its turning to one side (due to the slope of the ramp) and correct automatically. It worked like a dream.

the second function we used it for was compass heading. this is very easy to do - start out with a 16 bit variable, and add the yaw rate output to it on each loop, and subtract 127 to normalize the zero point.

you end up with a 16 bit number that is linear proportional to how many degrees you have turned left or right - dont even bother to try to make it look like 360° by dividing it, just use whatever units it comes out to be. 45° might be 4000 counts on the variable - this is easy to detemine with a little testing

as for the 70°/S rate - thats actually turning pretty quick if you are driving - there are few times when you would need to turn faster. In auton mode, if you wanted to turn 270° that would be slow - but we started out backwards and did a V turn, only needing to rotate 45° - and we were able to hit the center of the wall in about 3 seconds, very consistantly.

And if your driver really wants to turn faster than the yaw rate senosor allows (while the loop is closed) you can always program the top button on the joystick to open the loop.

Anthony Kesich 15-11-2003 12:44

Random Dude, thank you. Exactly what i was trying to hit on. When you declare just it, the compiler sees it a a short int unless you declare it as a long or long in in which case it is an int, but just holds a greater range of values. Or at least thats what Deitel & Deitel C and C++ books say along with my C for Dummies:D.

Dave Flowerday 15-11-2003 20:01

Quote:

Originally posted by Anthony Kesich
When you declare just it, the compiler sees it a a short int unless you declare it as a long or long in in which case it is an int, but just holds a greater range of values.
Anthony,
This is not correct. It happens to be true on the PIC C compiler. It is not true on all compilers.
Code:

$ cat sizeof.c
#include <stdio.h>

int main(void) {
  printf("Sizeof char: %d\n", sizeof(char));
  printf("Sizeof short int: %d\n", sizeof(short int));
  printf("Sizeof int: %d\n", sizeof(int));
}

$ gcc -o sizeof sizeof.c
$ ./sizeof.exe
Sizeof char: 1
Sizeof short int: 2
Sizeof int: 4
$


Andrew 16-11-2003 17:18

I haven't been keeping up with this whole discussion, so, if this is posted earlier in the thread, my bad.

However, the whole issue of data types and sizes in the PIC 18 series can be found in the user's manual for the compiler.

This manual is located in the compiler DOC directory. The compiler should be located at:
C:\mcc18 (or something close to that).

I was actually looking for the #pragma information (which is compiler specific) and found that plus more.

Anthony Kesich 17-11-2003 13:42

opps
 
sorry about that then. I've yet ot run into a compiler that is designed in such a way, but thats probably because i stick really to only 2 compilers. But to make it clear for myself, in is always going t be short int (2 bytes) or long int(4 bytes), never inbetween(3 bytes?), right? Or can it be?

Random Dude 17-11-2003 15:08

Actually, I just looked in the MPLAB-C18-USERS-GUIDE.pdf , and on page 13, (Section 2.1.1) there is the following

Quote:

In addition, MPLAB C18 supports a 24-bit integer type short long int (or long short int), in both a signed and unsigned variety.
There is also a nice table there that gives the sizes and ranges for all data types supported by the C18 compliler. These match my previous numbers, with the addition of the "short long" type.

Anthony Kesich 17-11-2003 17:52

ohhh unique variables=fun
thanks for the head up

rbayer 17-11-2003 20:39

Re: opps
 
Quote:

Originally posted by Anthony Kesich
But to make it clear for myself, in is always going t be short int (2 bytes) or long int(4 bytes), never inbetween(3 bytes?), right? Or can it be?
It can definately be in between on some systems. Take, for instance, a 64-bit processor. A long could be defined as 64-bits, a short as 16, and an int as 32. In general, variables will be an even number of bytes just because most processors access memory the most efficiently that way. However, as demonstrated by the short long int example earlier, this is not a strict requirement.

Moral of the story: any time you start using a new compiler or platform, run a simple sizeof program like the one Dave Flowerday posted. It's really the only way to know for sure what sizes each of the types are.

Burgabot 21-11-2003 22:01

Well, I used last year's gyro to successfully integrate the angular position, but I got a weird result. My integration was always approximately 29/36 of what it should be. I simply have to multiply the result by 36/29 in order to correct it, but I would still like to know why it does such a thing. The only thing that I can think of which would cause a proportional discrepancy is that the processor is running slowly. However, my program uses no division or floating point operations, so this makes no sense whatsoever. The only other thing which may mess it up is that I just throw out any gyro values between 6 and -6 (out of a range of -1024 to 1024) to account for the inaccuracy of the gyro when it's sitting still. What could be causing this?

Chris Hibner 02-12-2003 19:22

Re: Quick Question
 
Quote:

Originally Posted by Burgabot
Well, I used last year's gyro to successfully integrate the angular position, but I got a weird result. My integration was always approximately 29/36 of what it should be. I simply have to multiply the result by 36/29 in order to correct it, but I would still like to know why it does such a thing. The only thing that I can think of which would cause a proportional discrepancy is that the processor is running slowly. However, my program uses no division or floating point operations, so this makes no sense whatsoever. The only other thing which may mess it up is that I just throw out any gyro values between 6 and -6 (out of a range of -1024 to 1024) to account for the inaccuracy of the gyro when it's sitting still. What could be causing this?


I have a few suggestions...

1) First, I would suggest that you not throw out values. The values that you are getting when the gyro is sitting still is just typical noise. When you integrate, these "strange" values will average themselves out to zero, so don't worry about these values. In fact, they can help you out.

2) One possibility is that the gain of the sensor is not at it's nominal value. Most sensors have tolerances of about 5% for the gain. 29/36 is 80% (20% error), so obviously the gain isn't the entire problem (if it's a problem at all). Try the other suggestions. If you get it to within 10%, then I would just multiply by whatever factor that you're consistently off by, since the problem is most likely the gain of the sensor.

3) It is possible that the slow sample rate is also part of the problem. If you are using rectangular integration (simple sum), then your integral will usually be low if the input is a rising signal (which is most likely is for your test). You could try to use trapezoidal integration to help solve some of the problem. To use trapezoidal integration, average the current sample with the previous sample, and then add this to your sum. See the following example code:

// start of integral
// Remember to initialize GyroSensorPrevious to zero at startup
GyroSignal = RawGyroSignal - GyroBias;
IntegralInput = (GyroSignal + GyroSignalPrevious)/2;
Integral += IntegralInput; // or Integral += IntegralInput*GainFactor
GyroSignalPrevious = GyroSignal;
// end of integral


4) What are you doing for the sensor bias? You should always perform a sensor bias calculation when you power up your software. In other words, before you start running your integral, you should take an average of a large number of sensor readings. You can start with about 32 samples to see how that works. If your bias is not exact, it's easy for your integral to get off rather quickly.

5) Be sure your variables are scaled appropriately. Make sure you have some fractional-part bits (see my most recent white paper). This is not so important for the integral, but it is important for the bias average and for subracting that average off of the raw A/D value. When you truncate decimal portions, you always floor (i.e. round toward -infinity). Therefore, your integral will always be low.

6) Is your sample rate constant, or does it vary? If your sample rate is not consistent, your integral will not be very accurate, and you will have difficulty determining the problem.

7) When you ran your test, did you run it in both directions (i.e. counterclockwise AND clockwise). If so, do you get the same results?

8) Lastly (and maybe most importantly): You could be saturating the sensor. Are you ABSOLUTELY SURE that you're turning less than 50 deg/sec? I know that the sensor is rated for higher rates, but when you add noise to the signal, you will have problems with your integral. For instance, let's say you're turning at 55 deg/sec and you have 10 deg/sec of noise. The sensor outputs 5 V for 60 deg/sec. That means that the noise peaks will give you 60 deg/sec (it clips the peaks to 60 deg/sec, even though they should be 65 deg/sec), but the noise valleys are at 45 deg/sec. After averaging the noise in the integral, your angular rate appears to be about 52.5 deg/sec rather than 55 deg/sec. That is one of the many reasons why you need to be sure your sensor has adequate "head room" above your peak turning rate.

On this same point, if you are turning the sensor at a rate higher than it's peak output, you're integral is going to be low. The peak output can vary due to many reasons (and it can vary more than you would think), so you have to be sure you have headroom.

Whew, that was long. If you aswer the questions for each of these points, I can help you pinpoint the problem.

Good Luck,

Chris


All times are GMT -5. The time now is 09:01.

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