Subject:
|
Re: legOS lcd management and thoughts on velocities
|
Newsgroups:
|
lugnet.robotics.rcx.legos
|
Date:
|
Sat, 27 Jan 2001 20:22:23 GMT
|
Viewed:
|
1379 times
|
| |
| |
Thank you Jochen for your answer.
If I well understand the ds_rotation_handler code, the timeout is set to 1
second.
So the velocity may drop to zero 1 second after wheels really stop.
In the specific case of my robot (I call it R2D1), this will be a little bit
late.
I allready described R2D1 in a previous message but anyway here it is (again)
"*******************
Six parallel and non orientable wheels ( 3 on left side, 3 on right side ).
On each side the front and back wheels are mechanicaly linked and motorized
(OUT_A & OUT_C).
On each side the middle wheel is free and linked to a rotation sensor with a
1:3 ratio (input 1 & 3).
The RCX it self is mounted on a motorized (OUT_B) turret because I wanted to
have an oriantable IrRadar.
A light sensor and 2 switchs are mounted on input 2. The turret stroke is
limited to 180° (rcx wires pass thru it so it should not turn more!). The
switch indicates that the turret reach either -90 or 90°.
The way it moves:
Straight: both Left and Right Motors turn the four wheels. Middle wheel give
the distance.
Rotation: Left and Right Motors turn in opposite way. So the Robot act as a
caterpillar. The Wheels should be enough hard to skid smoothly during the
rotation. As the Middle wheel are exactly in the middle they don't prevent the
rotation of the robot.
*********************"
As you notice I choosed to have 2 rotations sensor and 1 light sensor, so R2D1
can't detect collision with switchs. Instead, he 'guess' that there is
collision when
1) he drive motor on and velocity drop down ( bump a wall )
2) he drive motor off and velocity is not null ( let say my daughter kick him!
)
So I would prefer that R2D1 'guess' collisions a soon as they occurs.
I'll try to change your timeout ( from 1000ms to 200ms ). The posibility to
change this timeout by software may be interresting.
There are other differences between ds_rotation_handler and my task.
1 )The task I wrote was naturally not as low level as yours. I used msleep(1)
to obtain a pseudo more or less 1KHz frequency. So the speed I compute will not
be as accurate as your velocity.
2)My Task will give up after only 200ms without a move and set speed to zero
quicker.
3)As soon as time interval between move is growing (but still inferior to
200ms) the speed is updated. This enable to decrease speed and so to warn,
before the 200ms, any other task using speed that the speed is going down. This
feature give a very good reactivity to R2D1
Here is the task "int Wheels::CountAndSpeed ( int argc, char **argv )" I wrote.
//**************************************************
#define LFT 0x00
#define RGT 0x01
#define NEW 0x00
#define OLD 0x02
#define LMotor motor_a_dir
#define RMotor motor_c_dir
volatile int Wheels::Delta[4];
volatile int Wheels::Timer[4];
volatile int Wheels::Count[4];
volatile int Wheels::Speed[4];
//volatile Situation Wheels::S;
void Wheels::CountAndSpeedInit ( void )
{
Count[LFT] = -ROTATION_1;
Count[RGT] = -ROTATION_3;
Count[LFT|OLD] = Count[LFT];
Count[RGT|OLD] = Count[RGT];
Speed[LFT|OLD] = Speed[LFT] = 0;
Timer[LFT|OLD] = Timer[LFT] = 0;
Speed[RGT|OLD] = Speed[RGT] = 0;
Timer[RGT|OLD] = Timer[RGT] = 0;
}
void Wheels::UpdateSpeed ( int s )
{
Timer[s]++;
Delta[s] = Count[s] - Count[s|OLD];
if ( Delta[s] )
{
// there were movement since last time
Speed[s]=(Delta[s]*1000)/Timer[s]; // Speed=Delta/Timer*1000 in Ticks/Sec
Count[s|OLD]=Count[s]; // update old value
Timer[s|OLD]=Timer[s]; // update old value
Delta[s|OLD]=Delta[s]; // update old value
Timer[s]=0; // reset timer
}
else if ( Timer[s] > 200 )
{
// 200ms without a move ==> Speed=0
Speed[s]=0;
Timer[s|OLD]=Timer[s]; // update old value
Timer[s]=0; // reset timer
}
else if ( Timer[s] > Timer[s|OLD] )
{
// Here speed is decreasing. While waiting next move, we (over)estimate it.
Speed[s]=(Delta[s|OLD]*1000)/Timer[s];// Speed=Delta/Time*1000 in Ticks/Sec
}
}
int Wheels::CountAndSpeed ( int argc, char **argv )
{
CountAndSpeedInit();
while( 1 )
{
msleep ( 1 );
Count[RGT] = -ROTATION_3;
Count[LFT] = -ROTATION_1;
UpdateSpeed (LFT);
UpdateSpeed (RGT);
}
exit(0);
}
//**************************************************
please feel free to comment or use my code ( or ideas hidden within it !).
best regards,
Michael.
|
|
Message has 1 Reply:
Message is in Reply To:
5 Messages in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
This Message and its Replies on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|