Emergence and inhibition of synchronisation in robot swarms
Fernando Perez-Diaz, Stefan M Trenkwalder, Ruediger Zillmer and Roderich Groß
Abstract
Synchronisation can be a key requirement to perform coordinated actions or reach consensus in multi-robot systems.
We study the effect of robot speed on the time required to achieve synchronisation using pulse coupled oscillators.
Each robot has an internal oscillator and the completion of oscillation cycles is signalled by means of short visual pulses. These can, in turn, be detected by other robots within their cone of vision.
In this way, oscillators influence each other to attain temporal synchrony.
We observe in simulation and in physical robotic experiments that synchronisation can be fostered or inhibited by tuning the robot speed, leading to distinct dynamical regimes.
In addition, we analyse the effect of the involved parameters on the time it takes for the system to synchronise.
Robotic trial videos
The long blue line marks approximately a 1 τ and the small blue line marks half of that interval.
The standard deviation (sd) of the histogram over the period τ is calculated when the mode of the sample passes over the short blue line.
Trial videos 1-5 for the following speeds can be found on this YouTube playlist.
- V=0.5 cm/s
- V=0.7 cm/s
- V=1.0 cm/s
- V=1.4 cm/s
- V=2.1 cm/s
- V=3.0 cm/s
- V=4.3 cm/s
- V=6.2 cm/s
- V=8.9 cm/s
- V=12.8 cm/s
Code
Motion algorithm
The motion of the robot is calculated, in simulation and experiments, independently to the synchronisation algorithm.
This following implementation is an illustration of the motion algorithm. For better readability, the code was simplified and functions have been renamed.
The function motionAlgorithm describes the entire implementation of the algorithm and is called periodically every 25 ms.
- Copy code
-
int motionAlgorithm(void){
getProximityValues();//get the values from the sensors
calculateProxPointer();//calculate the overall vector pointing to the centeroid of the obstacle
calculateMotorSpeed(&robot_speed);//calculate the motor speed from the vector//Set the motor speeds of the robot
Sys_Set_LeftWheelSpeed(robot_speed.left);
Sys_Set_RightWheelSpeed(robot_speed.right);
}
First, the sensor values of six sensors located on the front of the robot are obtained and stored in global buffers (proximity_values[]) by:
- Copy code
-
void getProximityValues(){
int new_value;for(int i = 0; i < PROXIMITIES; i++){// for each proximity sensor
if(Sys_Get_Prox(i) > 100){//measure if it is out of sensor range
proximity_values[i] = 0;
}else{//was something measured?
proximity_values[i] = 100-Sys_Get_Prox(i);
}
}
}
Then, the values of the directed proximity sensors are transformed into vectors where its length is an indicator of how close the measured obstacle is. These vectors are then summed to a vector that points towards the centroid of the measured obstacles.
- Copy code
-
void calculateProxPointer(){
int prox_x = 0;
int prox_y = 0;
int i,j;for(i = 5; i < 11; i++){ // sums all sensors from the front half
j = i % 8;
if(proximity_values[j] > 70){// if obstacle is close
prox_x += proximity_values[j] * angle_component_x[j];//calculate the X component
prox_y += proximity_values[j] * angle_component_y[j]);//calculate the Y component
}
}//store in global buffer
proximity_pointer.x = prox_x;
proximity_pointer.y = prox_y;}
The resulting vector is then used to calculate the wheel speeds and therefore the movement of the robot.
The robot follows the following rules:
- Move forward when no obstacle is detected.
- If an obstacle was detected on the left side, then rotate to the right side and vice versa.
- If the robot detected for a long time an obstacle in its surroundings, the robot rotates on the spot for a random amount of time to avoid potential life-locks.
- Copy code
-
void calculateMotorSpeed(motor_speeds *speeds){
static int rotTime = 0; // = counts the cycles that the robot was rotating
static int proxCount = 0; // = counts the cycles that the robot is close to an objectint vel = MAX_SPEED; // = robots velocity
int max = MAX_SPEED; // = 128 mm/s (maximum possible velocity)
int rotDir = 0; // = -1 for right and +1 for leftif(rotTime > 0 || proxCount > 0){ // if the robot is rotating or detected something
// is the X or Y component above threshold?
if( abs(proximity_pointer.x) > proxThres || abs(proximity_pointer.y) > proxThres ){
proxCount++;//Something was measured for an additional timestep
} else {
proxCount = 0;
}
}// If obstacles obstacle was right or left
if(proximity_pointer.y > 0){
rotDir = 1; //left
} else {
rotDir = -1; //right
}// If the robot was too long (> proxCountThres) close to an obstacle then turn away (for a random amount of time)
if(proxCount > proxCountThres){
speeds->left = - max*rotDir;
speeds->right = max*rotDir;
rotTime += 1 + (rand() % rotMax);
proxCount = 0;
}// If there is an obstacle ahead turn away
if(proximity_pointer.x > proxThres){
if(proxCount == 0){//if you haven't rotated before
speeds->left = -max*rotDir;
speeds->right = max*rotDir;
} else { // use lowpass to avoid life-lock by toggling direction due to noise
speeds->left = speeds->left/2 - max*rotDir/2;
speeds->right = speeds->right/2 + max*rotDir/2;
}
rotTime = 1;
} else {// if there is no obstacle
if(rotTime == 0) { // go forward
speeds->right = speeds->left = vel;
} else {// or continue last action until the robot finished rotating
rotTime -= 1;
}}
}
The presented algorithm was taken from the experiment implementation. However, the simulation used the same behaviour implemented in Python.
Simulations
The simulations were performed using the Enki library v2.0.
View and download the source code of the simulation.
Robotic experiments
The code ran on the robots during the experiments is a modified version of the OpenSwarm operating system.
View and download the used source code.
View and download the tracking software (requires OpenCv).
Appendix: synchronisation threshold
An approximate calculation of the equivalence between the synchronisation thresholds used in the simulations and the robotic experiments.
Download the appendix (PDF, 92KB)