measuring speed of the ActivityBot
BlackSoldierB
Posts: 45
What is the best way to calculate the speed of the ActivityBot?
My idea was to measure the time between two edges of the encoder.
This is my code:
The output is shown below, as you can see it deviates quite a bit.
I expect times around 15 milliseconds, is my method not accurate enough?
Maybe i can use the encoder function from the abdrive library, but it's really hard to understand with all the short variable names.
Does anyone have some tips for me?
My idea was to measure the time between two edges of the encoder.
This is my code:
#include "simpletools.h" #include "abdrive.h" #ifdef __PROPELLER_USE_XMM__ #define STACK_LONGS (1024+128+32+sizeof(_thread_state_t))/4 #else #define STACK_LONGS (16+sizeof(_thread_state_t))/4 #endif void calculateSpeed(void*); volatile static unsigned int timeInBetween; int main() { low(26); low(27); print("Starting\n"); unsigned int stack[STACK_LONGS + 25]; int cog = cogstart(&calculateSpeed, NULL, stack, sizeof(stack)); print("Started cog %d\n", cog); drive_speed(64,64); while(1) { print("dTime= %u\n", timeInBetween / (CLKFREQ/1000)); pause(100); } } void calculateSpeed(void*) { unsigned int prevTime; while(1) { prevTime = CNT; //Remember the current time while(!input(14)); //wait when pin 14 is low timeInBetween = CNT - prevTime; //Calculate the difference in time while(input(14)); //wait when pin 14 is high } }
The output is shown below, as you can see it deviates quite a bit.
I expect times around 15 milliseconds, is my method not accurate enough?
dTime= 17 dTime= 15 dTime= 17 dTime= 15 dTime= 22 dTime= 18 dTime= 19 dTime= 23 dTime= 18 dTime= 17 dTime= 17 dTime= 15
Maybe i can use the encoder function from the abdrive library, but it's really hard to understand with all the short variable names.
Does anyone have some tips for me?
Comments
Can i just divide the "abd_dlca" or "abd_dlc" with the "td" variable to get the correct speed?
A further improvement is to calculate the average over multiple samples.
EDIT: How do i use the "interactive_development_mode" function? My xbee pins are 9 and 8.
This particular measurement is in ticks per second, because the sample is over 1/10 second, and the distance traveled is multiplied by 10. At constant speeds, a larger sample time will reduce measurement uncertainty, but it also takes longer to measure. Your code can also add details like waiting for a transition before starting the measurement to reduce measurement error.
Ah, so you found the hidden development tools. Uh, they're kinda broken. ...but I'll bet there's some arlodrive test code that'll work well for you if harvested and adjusted for the ActivityBot. Let me go hunt that down. Be back in a while...
Circuits, libraries, and test code examples for TV remote, XBee, and ActivityBot are here:
TV Remote
http://learn.parallax.com/propeller-c-simple-devices/ir-receiver-and-remoteXBee
http://learn.parallax.com/propeller-c-simple-protocols/full-duplex-serialActivityBot
http://learn.parallax.com/activitybotWhen they are all verified to work, try the code below.
Note: The comments in the code have more info on remote control buttons and the values in the XBee display.
The calculated speed is the used as setpoint for the PID controller right?
With the following code i am trying to calculate the the time that has passed between two spokes, but for some reasons it fluctuates a lot.
Then i print the result every second with the following line:
I think that updating lastStateL and lastStateR outside of the if statements is going to lead to incorrect measurements. After that gets fixed, the measured speed may still be somewhat error prone because the time that it takes a spoke to pass by vs a space to pass by will vary with the distance between the wheel and the sensor. If the wheel has any wobble in it, the spoke time might be 60% of a cycle, and the space time might only be 40% when the wheel is closer to the sensor. When it's further away, the times might be the other way around. So, it would probably also help to take a full cycle (time of spoke + space) or even the average of several cycles.
Check the speedMonitor function in this example. It keeps track of speed based on a cycle (spoke + space).
When i do drive_speed(50,50), it will vary from 48 to 52 (when printing every 100 ms). This accuracy will probably good enough for my application.