
Every automated equipment which features at least an actuator must have also a system and a procedure for its actuators homing, and of course, this is also true for our Lego Mindstorms Ev3 robots. In this page, a procedure for manual actuators homing is described.
The homing procedure for an actuator is the automated or manual sequence by which the actuator itself is returned to a given position that the control system considers to be the its zero position.
A simple homing procedure for a linear axis actuated by an electric motor, for instance, consists in gently pulling back the axis, until a proximity sensor on the home position detects it; when the proximity sensor detects the axis, the control system stops its movement and reset its sensor readings to zero.
If the equipment does not have absolute encoders, exactly like our Lego Mindstorms Ev3 Motors, a procedure similar to the one described above must be executed at the beginning of each execution of a program.
The Ev3 Contact Sensor is not accurate enough to be effectively used as a homing sensor, and besides it’s just one and there are three motors to calibrate. So we need a manual procedure to reset the axis to the zero position before a program re-start.
Consider the R3PTAR: you need to calibrate the neck orientation and the neck contraction before starting your program to be sure that the program always start from the same zero position.

One way to do this, it is to take advantage of the Monobrick Ev3 Firmware and create a custom menu which can be used to manually home every actuator on board your robot. Simply, create an ItemWithNumericInput for each motor, and on the call back method use the Motor.SpeedProfileTime() method to jog the correspondent axis in the right direction; when you start the program, you will be able to manually home the axis before starting the actual robot program.
The custom menu is presented at the start of the robot program; you can use the up and down to select the desired actuator, and the left and right key to jog it to zero position.
The zero position is conventional and depends on how you have programmed the robot. For the R3PTAR program, the zero positions are with the straight snake body and with the contracted neck.
No need to dismantle the robot before each start anymore !
Code for the manual actuators homing
The C# code is the following:
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 79 80 81 82 83 84 |
/// <summary> /// Main class /// </summary> class MainClass { #region Static Fields private static int previousNeckValue = 0; private static int previousHeadValue = 0; #endregion static public MenuContainer container; public static void Main (string[] args) { Menu menu = new Menu ("Reptar"); container = new MenuContainer (menu); // menu.ParentMenuContainer = container; menu.AddItem(new ItemWithNumericInput("Calibrate Neck", 0, CalibrateNeck, -30, 30)); menu.AddItem(new ItemWithNumericInput("Calibrate Head", 0, CalibrateHead, -30, 30)); menu.AddItem (new MainMenuItem ("Start", Start_OnEnterPressed)); menu.AddItem (new MainMenuItem ("Quit", Quit_OnEnterPressed)); container.Show (); } public static void TerminateMenu() { container.Terminate (); } public static void CalibrateNeck (int newValue) { sbyte maxSpeed = 10; sbyte speed = 0; Motor Motor = new Motor (MotorPort.OutA); if (newValue > previousNeckValue) { speed = maxSpeed; } else { speed = (sbyte)-maxSpeed; } previousNeckValue = newValue; Motor.SpeedProfileTime (speed,100,100,100,true); } public static void CalibrateHead (int newValue) { sbyte maxSpeed = 10; sbyte speed = 0; Motor Motor = new Motor (MotorPort.OutC); if (newValue > previousHeadValue) { speed = (sbyte) - maxSpeed; } else { speed = (sbyte) maxSpeed; } previousHeadValue = newValue; Motor.SpeedProfileTime (speed, 100, 100, 100, true); } public static void Start_OnEnterPressed() { container.SuspendButtonEvents (); Reptar reptar = new Reptar (); reptar.Start (); container.ResumeButtonEvents (); } public static void Quit_OnEnterPressed() { LcdConsole.Clear (); LcdConsole.WriteLine ("Terminating"); // Wait a bit Thread.Sleep(1000); TerminateMenu (); } } |