| | | | |
| |
|
YAL: Yet Another LegWay
Allen Foster and
Harold Jarvie posts showed me that it
was possible to build a LEGO-only self-balancing robot, inspired by the famous
Steve Hassenplugs LegWay.
Here are some details of my implementation, using two regular light sensor to
monitor YAL inclination.
The code is a simple PID algorithm
implemented in BrickOS, direct translation of
Allen Foster code. The input comes
from front and back light sensors difference, the output is applied to both
motors.
Yal works best with diffused overhead lighting and doesnt like at all lateral
lights (windows)
Here are some movies (Quick Time, 0.5 to 1Mb)
Even Better : Frédéric Sivas single light sensor version
Frédéric modified the code to make YAL work using a single light sensor: a
RIS-only self balancing robot!
Here is Frédérics modified
code
Slightly less stable than its 2 sensors brother, it is nonetheless quite
convincing, as shown in this movie (AVI, 1Mb)
Congratulations, Frédéric!
Philo
Many thanks to John Hansen, whose
BricxCC and Cygwin/BrickOS
installers made BrickOS palatable to average Windows users like me !
| | | | | | | | | | | | | In lugnet.robotics, Philippe Hurbain wrote:
|
YAL: Yet Another LegWay
=======================
Congratulations, Frédéric!
Philo
Many thanks to John Hansen, whose
BricxCC and Cygwin/BrickOS
installers made BrickOS palatable to average Windows users like me !
|
This is really cool. Its great to see what everyones done with a really
simple idea. Very nice.
Steve
| | | | | | | | | | | | | | | Oooh!
I know what I'll be building this weekend!
Incredible well done, Steve showed the path and you guys walked it :)
--
Best regards,
/Tobbe
<http://www.lotek.nu>
(remove SPAM when e-mailing)
| | | | | | | | | | | | | | | In lugnet.robotics, Philippe Hurbain wrote:
Very nice, Philo. Looks very stable. I guess the next job is to get it to
respond to the LEGO remote ;) You could even implement forwards/backwards by
having the remote shift a weight on the LegWay!!
ROSCO
| | | | | | | | | | | | | | | In lugnet.robotics, Philippe Hurbain wrote:
|
YAL: Yet Another LegWay
Allen Foster and
Harold Jarvie posts showed me that
it was possible to build a LEGO-only self-balancing robot, inspired by the
famous Steve Hassenplugs
LegWay.
Here are some details of my implementation, using two regular light sensor to
monitor YAL inclination.
The code is a simple PID algorithm
implemented in BrickOS, direct translation of
Allen Foster code. The input comes
from front and back light sensors difference, the output is applied to both
motors.
Yal works best with diffused overhead lighting and doesnt like at all
lateral lights (windows)
|
I built one of these yesterday, and it works surprisingly well! I like the very
simple design. Like Steve Hs original LegWay, it requires very few parts.
Although it is a little tricky to put it together.
I found that the performance of the robot is highly dependent on a couple of
factors:
- Solid-color, bright or white floor seems to work better than patterned floors.
- You have to hold the robot perfectly vertical when you start the program so that it gets a good offset reading between the two light sensors. The better you do this, the better the resulting balance.
- Works best in a dark room with no lights pointing directly at the robot.
Very nice job! It makes me want to add some code to make it move around and
chase the cats.
I have to second this. John has done a very nice job with BricxCC. He has also
made it possible for me to finally get a working GCC installation with BrickOS
on my Windows 98SE machine. Thanks, John!
- Chris.
| | | | | | | | | | | | | | | | | |
| |
| <snippage>
> * Solid-color, bright or white floor seems to work better than patterned floors.
> * You have to hold the robot perfectly vertical when you start the program so
> that it gets a good "offset" reading between the two light sensors. The
> better you do this, the better the resulting balance.
> * Works best in a dark room with no lights pointing directly at the robot.
</snippage>
i'm thinking that making a vertical frame to start it would help. something
like two support barsthat are vertical in which you would put the YAL to
start it off in a perfectly vertical position. you could even make it hinged
on one side so you could program a short burst of speed after registering
"vertically" which would allow it to get out of the frame by itself.
also, perhaps adding a third motor with an weight (micro-motor?) that could
be offset to change the center of gravity slightly could give the YAL
direction to go. like forcing it to tip and move in the direction of the
tip.
and final thought, it would seem that YAL is pretty much a lateral motion
bot, so maybe it would be easier for it to balance with a solid axle?
just a few thoughts.
regards,
mike
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.576 / Virus Database: 365 - Release Date: 1/30/2004
| | | | | | | | | | | | | | | | In lugnet.robotics, Philippe Hurbain wrote:
|
YAL: Yet Another LegWay
Here are some details of my implementation, using two regular light sensor to
monitor YAL inclination.
The code is a simple PID algorithm
implemented in BrickOS, direct translation of
|
Hey Philo,
I was just looking over your code, and I think if you change this line:
pid = (Kd * errdiff + Kp * err + Ki * errint) /3000l;
to something like this:
pid = (Kd * errdiff + Kp * err + Ki * errint) /3000l + ForwardOffset;
then when you change ForwardOffset (via remote control code) the robot will
start to go forward (or backward, if its negative).
The ForwardOffset could be between -255 and 255 (Im sure you dont want it
quite that big)
Steve
| | | | | | | | | | | | | | | | | |
| |
| Hello Steve,
Monday, February 9, 2004, 8:55:11 PM, you wrote:
SH> In lugnet.robotics, Philippe Hurbain wrote:
> > YAL: Yet Another LegWay
> > =======================
> >
> > Here are some details of my implementation, using two regular light sensor to
> > monitor YAL inclination.
> >
> > The [<http://www.philohome.com/yal/yal1.c code>] is a simple PID algorithm
> > implemented in BrickOS, direct translation of
SH> Hey Philo,
SH> I was just looking over your code, and I think if you change this line:
SH> pid = (Kd * err_diff + Kp * err + Ki * err_int) /3000l;
SH> to something like this:
SH> pid = (Kd * err_diff + Kp * err + Ki * err_int) /3000l + ForwardOffset;
SH> then when you change ForwardOffset (via remote control code) the robot will
SH> start to go forward (or backward, if it's negative).
SH> The ForwardOffset could be between -255 and 255 (I'm sure you don't want it
SH> quite that big)
SH> Steve
Or, you could just alter the original offset that is calculated when
you first turn it on. I used this method to get it to move forward and
back. Then it's easy to get the robot to rotate by implementing one of
the PID controllers for each of the wheels with opposite offsets.
Allen
--
Best regards,
Allen mailto:Kaptain.korolev@ntlworld.com
| | | | | | | | | | | | | | | | | | | |
| |
| > > Hey Philo,
> >
> > I was just looking over your code, and I think if you change this line:
> > pid = (Kd * err_diff + Kp * err + Ki * err_int) /3000l;
> > to something like this:
> > pid = (Kd * err_diff + Kp * err + Ki * err_int) /3000l + ForwardOffset;
> >
> > then when you change ForwardOffset (via remote control code) the robot will
> > start to go forward (or backward, if it's negative).
> > The ForwardOffset could be between -255 and 255 (I'm sure you don't want it
> > quite that big)
>
> > Steve
>
> Or, you could just alter the original offset that is calculated when
> you first turn it on. I used this method to get it to move forward and
> back. Then it's easy to get the robot to rotate by implementing one of
> the PID controllers for each of the wheels with opposite offsets.
>
> Allen
Hi Steve and Allen,
I already tried what you suggested, but I had only mixed results: either too
little moves or unstable and uncontrolable ones. Perhaps also my PID
coefficients, determined by trial and error, are not so good...
I'd like to have more time to tune all this!
Philo
| | | | | | | | | | | | | | | | | | | | Hi Philo,Steve and Allen.
I've made a YAL right after reading the articles of you all.
It's great and very fun.
After tuning some papameters, it is working so well.
My Lego has been in a dark corner of my room so long time.
New BrickCC/BrickOS help me to follow up all procedures easily.
But, I don't know about "remote control code" !
> > > pid = (Kd * err_diff + Kp * err + Ki * err_int) /3000l + ForwardOffset;
> > >
> > > then when you change ForwardOffset (via remote control code) the robot
Please let me know and try to control this Legway in better way.
Kitak.
ps. I've wated for 10 days to get a admission for posting...;
| | | | | | | | | | | | | | | | | | | | Im lazy . . . would someone please write a version of the program that works
with the LEGO remote control? Using the remote control is cooler than driving it
with a flashlight. And with a flashlight you cant make it turn.
| | | | | | | | | | | | | | | | | | | | In lugnet.robotics, Jordan Bradford wrote:
|
Im lazy . . . would someone please write a version of the program that works
with the LEGO remote control? Using the remote control is cooler than driving
it with a flashlight. And with a flashlight you cant make it turn.
|
Okay, I tried writing it anyway. It doesnt work, and I think its because Im
not changing the motor speeds. All Im doing is changing motor directions. Help
me out, please, since I spent the time to install BrickOS in BricxCC and learn
the remote.h and dsound.h APIs. Thanks!
#include <conio.h>
#include <unistd.h>
#include <dmotor.h>
#include <dsensor.h>
#include <dbutton.h>
#include <remote.h>
#include <rom/lcd.h>
#include <dsound.h>
int directionA, directionC;
int remote(unsigned int etype, unsigned int key)
{
if(etype == LREVT_KEYON)
{
switch(key)
{
case LRKEY_BEEP:
dsound_system(DSOUND_BEEP);
break;
case LRKEY_A1:
directionA = fwd;
break;
case LRKEY_A2:
directionA = rev;
break;
case LRKEY_C1:
directionC = fwd;
break;
case LRKEY_C2:
directionC = rev;
break;
case LRKEY_STOP:
break;
}
}
return 1;
}
int main(int argc, char **argv) {
long offset;
long err, err_diff, err_int = 0, err_old;
long pid;
int Kd = 210, Kp = 180, Ki = 10;
ds_active(&SENSOR_1);
ds_active(&SENSOR_3);
msleep(20);
offset = (long)SENSOR_1 - (long)SENSOR_3;
cputs("yal1");
sleep(2);
err_old = 0;
lr_init();
lr_startup();
lr_set_handler(remote);
while(1)
{
err = (long)SENSOR_1 - (long)SENSOR_3 - offset;
err_int = err_int + err + err_old;
err_diff = (err - err_old);
err_old = err;
pid = (Kd * err_diff + Kp * err + Ki * err_int) /3000l;
if (pid > 255) pid = 255;
if (pid < -255) pid = -255;
if (pid < 0)
{
directionA = rev;
directionC = rev;
pid = -pid;
}
else
{
directionA = fwd;
directionC = fwd;
pid = pid;
}
if (pid < 5)
{
directionA = brake;
directionC = brake;
}
lcd_int(pid);
lcd_refresh();
motor_a_dir(directionA);
motor_a_speed(pid);
motor_c_dir(directionC);
motor_c_speed(pid);
if(PRESSED(dbutton(), BUTTON_PROGRAM))
{
motor_a_dir(brake);
motor_c_dir(brake);
ds_passive(&SENSOR_1);
ds_passive(&SENSOR_3);
cputs("stop");
msleep(300);
while (PRESSED(dbutton(), BUTTON_PROGRAM));
motor_a_dir(off);
motor_c_dir(off);
cls();
lr_shutdown();
return(0);
}
msleep(20);
}
}
|
|
Some other things:
-Is there any reason the Prgm button is being used to stop the program? Why not
just press the Run button again, like in the normal firmware? -How can I make
the Stop button on the remote do what the program currently does when Prgm is
pressed? Maybe Ill cheat and use a goto.
Thanks again!
| | | | | | | | | | | | | | | | In lugnet.robotics, Maurits Kooiman wrote:
| | | | | | | | | | | | | | | | | In lugnet.robotics, Maurits Kooiman wrote:
|
In lugnet.robotics, Maurits Kooiman wrote:
|
Whaoooo! impressive!!!
Philo
| | | | | | |