HITI Motor Group (Synchronized Group)

Modified on Thu, 5 Jan, 2023 at 2:13 PM

A HITI Motor Group is a variable which lets you synchronize the motions of several HITI Servos moving at the same time (they start and stop their motions at the same time). To synchronize the motions of several Servos, simply put them in the same Motor Group (available for Finite Motions only, not for Continuous Motions).


To illustrate this, let’s synchronize 3 Servos by adding them to the same Motor Group. We will make a back-and-forth motion sequence of all the servos.



Sketch

Upload this sketch : 5_MotionControl \ 4_SynchronizedGroup


We start our code by including the HC_Servo.h and HC_MotorGroup.h libraries, and by creating 3 HITI Servo variables and 1 HITI Motor Group variable.


We also assign several HITI Data to different control parameters to control and monitor the Motor Group from HITIPanel :

  • Current position of all Servos
  • Max speed of Servo 1
  • Target motion time of the Group
  • “START” and “STOP” buttons
  • State of the Group (can be Ready or Moving)


Finally, we create a variable called step whose value represents the number of the step being executed during the motion sequence. Step will take the values 0 to 2.


#include <HITIComm.h>
#include <HC_Servo.h>
#include <HC_MotorGroup.h>

// pins assignment 
const int pin_Servo_1 = 8;  // servos
const int pin_Servo_2 = 9;
const int pin_Servo_3 = 10;

// Analog Data assignment
const int ad_Step         = 0; // sequence step
const int ad_Position_S1  = 1; // current positions (Servos 1-3)
const int ad_Position_S2  = 2;
const int ad_Position_S3  = 3;
const int ad_maxSpeed_S1  = 4; // max speed (Servo 1)
const int ad_motionTime_G = 5; // motion time (Group)

// Digital Data assignment
const int dd_Start        = 0; // virtual buttons
const int dd_Stop         = 1;
const int dd_isReady_G    = 2; // group state
const int dd_isMoving_G   = 3;

// motion sequence in 5 steps: 0 (Ready), 1-2 (Motions)
int step = 0;

// max speed (servo 1)
float maxSpeed_S1 = 100.0;

// HITI Motor Group
HC_MotorGroup group;

// HITI Servo
HC_Servo servo_1;
HC_Servo servo_2;
HC_Servo servo_3;


During the setup(), we start by initializing the 3 Servos individually and by giving them different servo IDs (1, 2 and 3). These IDs will be used by the Group to address them. 


Next, we initialize the Group by specifying that it will contain exactly 3 Servos, and we add the Servos to it.


Finally, we set the max speed of Servo 1 and we display its initial value in HITIPanel. As we will see after, the max speed of one of the Servo can impact the whole Group.

 

void setup()
{
    // 1) initialize library
    HC_begin();

    // 2) initialize HITI Servos
    // param: servo ID, pin, invert direction, position offset, absolute init position
    servo_1.init(1, pin_Servo_1, true,  3,  20);
    servo_2.init(2, pin_Servo_2, false, -1, 40);
    servo_3.init(3, pin_Servo_3, false, 0,  60);
    
    // 3) initialize HITI Motor Group and add Servos to it
    group.init(3);
    group.add(&servo_1);
    group.add(&servo_2);
    group.add(&servo_3);

    // 4) set max speed of Servos, if required (affect motion time)
    servo_1.maxSpeed(100); // °/s

    // 5) display initial values of the control parameters in HITIPanel
    HC_analogDataWrite(ad_maxSpeed_S1, maxSpeed_S1); // max speed (servo 1)
}


We then prepare the function onMotionDone() that will be called each time a motion ends.  Its role is to update the steps to create the motion sequence.


// called each time a motion ends
void onMotionDone()
{
    // at end of steps 0-1
    if (step < 2)
        step++;   // go to next step

    // at end of step 2
    else
        step = 0; // go to step 0
}


Inside the loop(), we start by reading the value of the max speed of Servo 1 set from HITIPanel and we apply it.


void loop()
{
    // communicate with HITIPanel
    HC_communicate();


    // set new control parameters --------------------------------------------

    // read from HITIPanel
    maxSpeed_S1 = HC_analogDataRead(ad_maxSpeed_S1);

    // set max speed (servo 1)
    servo_1.maxSpeed(maxSpeed_S1);


Next, the motion sequence is started if the “START” button is clicked and if the sequence is ready to start (step 0).


Immediately after, we check if the “STOP” button is clicked to know if the sequence must be stopped. The sequence can be stopped at any steps and at any moment. The STOP has priority over the processing of steps 1 to 4, therefore it is checked before executing these steps.


The sequence steps are executed one after the other. At each step, the Servos perform a synchronized motion. Their positions are set individually using relativePosition(servo ID, setpoint), and the Group motion time is set using motionTime(time).


    // start/stop motion sequence --------------------------------------------
    
    // step 0: ready to start sequence with the START button
    if((step == 0) && HC_digitalDataRead(dd_Start))
    {
        step = 1; // start sequence
    }
   
    // at any step: stop sequence with the STOP button
    if(HC_digitalDataRead(dd_Stop))
    {
        group.stopNow(); // stop group
    
        step = 0;          // reset sequence
    }
    
    // step 1
    else if(step == 1)
    {
        // move group
        group.relativePosition(1, 10);  // Servo 1: +10°
        group.relativePosition(2, 50);  // Servo 2: +50°
        group.relativePosition(3, 90);  // Servo 3: +90°
        group.motionTime(1.5);          // 1.5s
        group.moveNow();
    
        // when motion ends
        if(group.isEnding())
            onMotionDone();
    }
    
    // step 2
    else if(step == 2)
    {
        // move group
        group.relativePosition(1, -10); // Servo 1: -10°
        group.relativePosition(2, -50); // Servo 2: -50°
        group.relativePosition(3, -90); // Servo 3: -90°
        group.motionTime(4);            // 4s
        group.moveNow();
    
        // when motion ends
        if(group.isEnding())
            onMotionDone();
    }
    
    // deactivate the Virtual Buttons
    HC_digitalDataWrite(dd_Start, false);
    HC_digitalDataWrite(dd_Stop,  false);

 

Finally, we display the following data in HITIPanel: 

  • Sequence step 
  • Position (Target, Current) of all Servos
  • Motion time (Target) of the Group
  • Group state (Ready or Moving) 


    // display data in HITIPanel ---------------------------------------------
    
    // sequence step
    HC_analogDataWrite(ad_Step, step);
    
    // current positions (servos)
    HC_analogDataWrite(ad_Position_S1, servo_1.getCurrentPosition());
    HC_analogDataWrite(ad_Position_S2, servo_2.getCurrentPosition());
    HC_analogDataWrite(ad_Position_S3, servo_3.getCurrentPosition());
   
    // motion time (group)
    HC_analogDataWrite(ad_motionTime_G, group.getMotionTime());
    
    // state (group)
    HC_digitalDataWrite(dd_isReady_G,  group.isReady());
    HC_digitalDataWrite(dd_isMoving_G, group.isMoving());
}


 

Control Panels

1) Display the DATA Control Panels

2) The Servos are at their initial positions and the Group is Ready to move.



3) Click on “START” to start the motion sequence.



4) Follow the motion sequence by looking at the step being executed. Also, check the motion time of each motion (should be 1.5s for motion 1 and 4s for motion 2).



5) Change the max speed of Servo 1 to 2°/s and restart the motion sequence.


 

6) As you can see, this parameter is affecting the motion times of the Group. Indeed, in order to respect the max speed of Servo 1, the Group had to increase its motion times accordingly. Both motion 1 and 2 have their time increased to 5s.

 


7) Change the max speed of Servo 1 back to 100°/s.



 

Chart

1) Open the Chart window.

2) Start data acquisition. The servos positions are then plotted, and new data are added every 10ms and only the last 12s are displayed.

3) In the DATA Control Panels, click on “START” to start a new motion sequence.

4) When the motion is finished, stop data acquisition. As you can see, the Servos start and stop moving at the same time: their motions are correctly synchronized.


 




 

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons

Feedback sent

We appreciate your effort and will try to fix the article