
In this section, I’ll show how to program the Sentin3l to walk using C# and the Monobrick firmware library. The goal for the program for our little Lego Mindstorms Ev3 Sentin3l droid is to follow the command of the Ev3 IR Remote. To meet this goal, we have to program the droid in such a way that
- the droid reacts to the commands received from the Ev3 IR Remote
- the two Ev3 Large Motor move the legs in synchronized steps
Download the full code on GitHub!
Responding to the commands received from the Ev3 IR Remote
The commands that the Sentin3l can receive from the Ev3 Remote through the Ev3 IR Sensor are:
- Walk forward
- Walk backward
- Turn right
- Turn left
- Fire
So consider the following structure which is useful to interact with the Ev3 IR Remote:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/// <summary> /// Ev3 IR Remote Command /// </summary> public enum Direction { Stop = 0, Straight_Forward, Left_Forward, Right_Forward, Straight_Backward, Left_Backward, Right_Backward, Beacon_ON } |
which defines the type of the SENTIN3L direction :
1 2 3 4 |
/// <summary> /// Direction of Sentin3l motion /// </summary> public Direction direction; |
Please note, that of all the movements defined by the Direction enumeration, the SENTIN3L does not not use Left_Backward and Right_Backward , while Left_Forward and Right_Forward simply means turn left on the spot and turn right on the spot.
Then within the IRRemoteTask , the OnTimer() method assigns direction which the SENTIN3L has to take according to the commands received from the Ev3 IR Remote:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
private void OnTimer(Robot robot) { remoteCommand = ((Sentin3l)robot).irSensor.ReadRemoteCommand(); switch (remoteCommand) { case 0: ((Sentin3l)robot).direction = Direction.Stop; if (previousDirection != Direction.Stop) { LcdConsole.WriteLine("Stop"); previousDirection = Direction.Stop; beaconActivated = false; } break; case 1: ((Sentin3l)robot).direction = Direction.Left_Forward; if (previousDirection != Direction.Left_Forward) { LcdConsole.WriteLine("Left_Forward"); previousDirection = Direction.Left_Forward; beaconActivated = false; } break; case 3: ((Sentin3l)robot).direction = Direction.Right_Forward; if (previousDirection != Direction.Right_Forward) { LcdConsole.WriteLine("Right_Forward"); previousDirection = Direction.Right_Forward; beaconActivated = false; } break; case 5: ((Sentin3l)robot).direction = Direction.Straight_Forward; if (previousDirection != Direction.Straight_Forward) { LcdConsole.WriteLine("Straight_Forward"); previousDirection = Direction.Straight_Forward; beaconActivated = false; } break; case 8: ((Sentin3l)robot).direction = Direction.Straight_Backward; if (previousDirection != Direction.Straight_Backward) { LcdConsole.WriteLine("Straight_Backward"); previousDirection = Direction.Straight_Backward; beaconActivated = false; } break; case 9: ((Sentin3l)robot).direction = Direction.Beacon_ON; if (previousDirection != Direction.Beacon_ON) { LcdConsole.WriteLine("Beacon_ON"); previousDirection = Direction.Beacon_ON; beaconActivated = true; } break; default: ((Sentin3l)robot).direction = Direction.Stop; break; } } |
Program the SENTIN3L to walk
Now, to program the sentin3l to walk, we need to add the task that drives the two Ev3 Large Motors according to the command received by the Ev3 IR Sensor. Before doing that, let’s add an angular position PID regulator for each leg (see here for a PID -proportional integrative derivative- regulator description).
1 2 3 4 5 6 7 8 9 |
/// <summary> /// PID Task controlling the left leg angular position /// </summary> public LegMotorControl leftLegMotorControlTask; /// <summary> /// PID Task controlling the right leg angular position /// </summary> public LegMotorControl rightLegMotorControlTask; |
Then we can define the DriveTask as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/// <summary> /// Periodic Task that drives the Sentin3l /// </summary> public class DriveTask : PeriodicTask { #region Fields // Left leg angular position set point int leftLegSp; // Right leg angular position set point int rightLegSp; #endregion ... } |
Now it’s easy to move the SENTIN3L legs in sync: we need to change the regulators set point only when both motors have reached their set point within a certain threshold. And to turn? To turn left we change the left set point with a negative increment and the right set point with a positive increment:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
private void OnTimer(Robot robot) { // Adjust the LED Pattern if (((Sentin3l)robot).direction == Direction.Stop) { Buttons.LedPattern(3); } else if (((Sentin3l)robot).direction == Direction.Beacon_ON) { Buttons.LedPattern(2); } else { Buttons.LedPattern(1); } // Move the SENTIN3L // If the Legs have reached their previous set point if ( (Math.Abs(((Sentin3l)robot).leftLegMotor.GetTachoCount() - leftLegSp) < 10) && (Math.Abs(((Sentin3l)robot).rightLegMotor.GetTachoCount() - rightLegSp) < 10) ) { // Updates the set point switch (((Sentin3l)robot).direction) { case Direction.Beacon_ON: leftLegSp = leftLegSp + 0; rightLegSp = rightLegSp + 0; break; case Direction.Stop: leftLegSp = leftLegSp + 0; rightLegSp = rightLegSp + 0; break; case Direction.Straight_Forward: leftLegSp = leftLegSp + 180; rightLegSp = rightLegSp + 180; break; case Direction.Straight_Backward: leftLegSp = leftLegSp - 180; rightLegSp = rightLegSp - 180; break; case Direction.Left_Forward: leftLegSp = leftLegSp - 180; rightLegSp = rightLegSp + 180; break; case Direction.Right_Forward: leftLegSp = leftLegSp + 180; rightLegSp = rightLegSp - 180; break; case Direction.Left_Backward: leftLegSp = leftLegSp + 0; rightLegSp = rightLegSp + 0; break; case Direction.Right_Backward: leftLegSp = leftLegSp + 0; rightLegSp = rightLegSp + 0; break; default: leftLegSp = leftLegSp + 0; rightLegSp = rightLegSp + 0; break; } // Send the updated set point to the legs controller ((Sentin3l)robot).leftLegMotorControlTask.SetPoint = leftLegSp; ((Sentin3l)robot).rightLegMotorControlTask.SetPoint = rightLegSp; } // Fire if (((Sentin3l)robot).direction == Direction.Beacon_ON) { ((Sentin3l)robot).bodyMotor.SetPower(100); } else { ((Sentin3l)robot).bodyMotor.SetPower(0); } } |
Download the code from GitHub and try by yourself!
And don’t forget to rate this post! Thank you!
i’m a Mac user can i get the coding in a file a can open with my Mac
Hello Rob,
Sorry for this late reply…
I’m a Mac user too, so I think I can try to help you.
What tool did you use to program the Lego Mindstorms Ev3 so far?
Ciao,
Riccardo.
Ps. Merry Christmas!!!
Can we add more command?
Hello Novian,
Yes of course you can!
If you need help, please ask!
Cheers,
Riccardo.
Original: this program dapat mebantu.. tapi saya berharap coding ini lebih lengkap lagi
Translated: this program can help .. but I hope this coding is more complete
Original: Thanks a lot! What can I improve?
Translated: Terima kasih banyak-banyak! Apa yang boleh saya tingkatkan?
nice blog
Many thanks!