Formations

In this session we will introduce one of the tools available for use with drone exams, specifically 2D and 3D formations.

Motivation

For both spectacle and engineering, geometric shapes have multiple applications and a unique beauty. In the Swarm in Blocks folder, which can be found on the team's GitHub, you can find a file written in Python called formation.py, in which all the functions for each 2D formation and some basic 3D ones are written, all those presented in the list below:

Formation 2D

  • Line

  • Circle

  • Full square

  • Empty square

  • Triangle

Formation 3D

  • Cube

  • Pyramid

  • Sphere

How it works

The formation file is responsible for calculating the position that each Clover should be, to store all this, an array was created, which will be the return of the function, for this, the group used the Numpy library. The array contains the corresponding coordinates of each drone.

def circle(N, L=2):
    xc = yc = 0
    coord = np.empty((0,4))    #Numpy array
    z0 = 1
    logging.debug("Beginning circle formation")
    angle = 2*pi/N
    for idx in range(N):
        xi = L*np.cos(idx*angle)
        yi = L*np.sin(idx*angle)
        point = [round(xc+xi,2), round(yc+yi,2), z0, 1]
        coord = np.concatenate((coord,[point]))
    logging.debug("Circle done\n")
    return coord

In this example, we create a Numpy empty array, so that later the function enters a loop where some calculations can be done to assign the value of each coordinate. After that, this value is passed to a list that will be finally concatenated, generating an array of four columns and N rows, the fourth column is a necessary parameter for transformations.

The swarm.py class file is responsible for receiving and applying all the other scripts. The function below is responsible for collecting the parameters passed in the menu and calling the function from the formation file. After receiving the array it translates the coordinates, so that the center of the formation becomes the point (0,0) on the map.

   def setFormation2D(self, shape, N, L):
      if (shape=='line'):
         coord = formation.line(N, L)
      elif (shape=='full_square'):
         coord = formation.full_square(N, L)
      elif (shape=='empty_square'):
         coord = formation.empty_square(N, L)
      elif (shape=='circle'):
         coord = formation.circle(N, L)
      elif (shape=='triangle'):
         coord = formation.triangle(N, L)
      else:
         raise Exception('Formation input doesn\'t match any built-in formations')
      self.des_formation_coords = coord

      # Translate formation for current formation pose
      tx, ty, tz = self.des_formation_pose[0], self.des_formation_pose[1], self.des_formation_pose[2]
      self.des_formation_coords = transform.translateFormation(self.des_formation_coords, tx, ty, tz)

      # Update formation name
      self.des_formation_name = shape
      self.formation_list['formation {}'.format(self.op_num)] = {'name':self.des_formation_name, 'coord':self.des_formation_coords}
      self.op_num += 1

In the menu that appears after calling this node, you can choose which formation you want by entering the size of the geometric shape. The next command would be Apply to start positioning the drones, or Plot to preview the chosen formation.

-----Basic operations-----
1 - Takeoff all
0 - Initial position
L - Land all
RL - Return and Land
led - Set Led for all drones

-----Formations-----
2 - Line formation
3 - Triangle formation
4e - Empty square formation
4f - Full square formation
O - Circle formation
5 - Cube formation
6 - Sphere formation
7 - Pyramid formation
A - Alphabet formation
3D - Formation 3D

-----Transformations-----
TR - Rotate
TS - Scale
TT - Translate

-----LED EFFECT-----
LED1 - Led All
LED2 - Led Even
LED3 - Led Formation
LED4 - Led Odd
LED5 - Led Random

-----Plot and Apply-----
AP - Apply formation
PLT - Plot preview
PLT3D - Plot 3D preview
FL - Formation list

E - Exit

How to use it

You can use this tool in two ways: the first would be to make the drones appear already in the desired formation, just by providing the TakeoffAll command in the menu. Like below:

roslaunch swarm_in_blocks simulation.launch num:=3 formation:=triangle

This second command should be done in a second terminal, you can choose the flight modes and then choose whether the simulation is already running or not. This way is also using the command below, because it also shows the options of formations that can be chosen. After that and supplying the side, the next command in the menu would be ap, or plt, or plt3d.

python3 ~/catkin_ws/src/swarm_in_blocks/swarm_examples/src/terminal_control.py 

Last updated