A quadcopter simulator with single and multi-quad simulations. The simulator supports time scaling (including real-time simulations) and headless mode (the simulator runs in background without a GUI update).
Single Quadcopter Simulation
Multi Quadcopter Simulation
- Simulation of dynamics:
- Numpy
- Math
- SciPy
- GUI:
- Matplotlib
- Matplotlib Mapping Toolkits
- Threading:
- Time
- Datetime
- Threading
Clone the repository, move into the directory, and run the code:
$ git clone https://github.com/abhijitmajumdar/Quadcopter_simulator.git
$ cd Quadcopter_simulator
$ python quad_sim.py --sim single_p2p
Single quad with point to point control simulator:
$ python quad_sim.py --sim single_p2p
Multi quad with point to point control:
$ python quad_sim.py --sim multi_p2p
single quad with x-y velocity control:
$ python quad_sim.py --sim single_velocity
Changing time scaling, dynamics update time and controller update time:
$ python quad_sim.py --sim single_p2p --time_scale 0.5 --quad_update_time 0.002 --controller_update_time 0.005
These parameters can also be changed by editing the script quad_sim.py, which will however be overridden by command line arguments, if provided.
The main classes which define the simulator are Propeller, Quadcopter and GUI. There is also a sample Controller classes, which implements a controller for the quadcopter. The objective was to make a quadcopter dynamic simulator, which allowed us to control each motor individually. The other requirement was the ability to run the simulations in the background, hence possibly expediting the computations, commonly referred to as the headless mode. Once the simulator thread is started, the GUI may or may not be updated at the developers will. There is also a time scaling factor, which can allow the simulation to run as fast as the processor supports, and as slow as one can fall asleep doing so.
This class defines the thrust generated by a propeller of a specified size at a given speed of rotation. This was based on the equation provided on http://www.electricrcaircraftguy.com/2013/09/propeller-static-dynamic-thrust-equation.html. This was made into a separate class to enable the implementation of other multi-rotors as well.
This class performs the simulations of the dynamics based on the state space solution of a quadcopter. It uses 4 objects of the Propeller class to implement the quad configuration of a quadcopter. The state space representation of a quadcopter model have been adapted from Quadcopter Dynamics, Simulation, and Control by Andrew Gibiansky and Quadrotor Dynamics and Control by Randal Beard. The class is initialized using the quadcopter parameters like length of an arm, the weight of the quadcopter, radius of a sphere representing the center blob of the quadcopter, etc. It is defined in a dictionary which can be modified.
The state space is defined as: X = [x,y,z,x_dot,y_dot,z_dot,theta,phi,gamma,theta_dot,phi_dot, gamma_dot]. The update to the state is performed by an ODE solver from the current state to a new state over a period of dt time(defined by user). It uses the vode ODE solver available from the SciPy library. It has an update method to update the state, which is run on a thread at intervals defined by the time scaling factor. The thread can be started by the start_thread method.
It has methods to set_motor_speeds(), get_orientation(), get_position(), get_angular_rate(), get_linear_rate(), set_position() and set_orientation(), which can be used by the controller.
The GUI initialization takes in the same quadcopter parameter directory. It is optional to pass in the get methods for position and orientation of the quadcopter to the GUI initialization. It uses Matplotlib to plot a representation of the quadcopter, each update of which takes significantly more time than the quadcopter class update. It can be updated using the method update(), with the position and orientation of the quadcopter if the get methods are not defined while initializing the object.
A demo to implement a controller class. It is initialized using the quadcopter object and a controller parameter dictionary. The quadcopter object is used to update the global time as well as the quadcopter state and also to set the motor speeds on the quadcopter. An example parameter dictionary is provided which defines the different constants used by the controller. The update() method updates the motor speeds based on the control algorithm. The start_thread() method initializes the thread to keep updating the controller every update_rate(specified by the user).
Two example implementation of controller class are provided. One is to implement a point to point controller which controls to move the quadcopter to a desired (x,y,z) location. The other is a velocity controller, which controls to set the (x,y) velocity of the quadopter as desired, while using the z to set the quadcopter altitude. The velocity controller class is inherited from the point-to-point class, since the only change is in the update method, and can be used as an example to implement other type of controllers.
- TIME_SCALING: Used to define how fast the simulator runs. Value of 1.0 corresponds to real-time simulations. Any smaller number makes the simulation faster and vice versa. A value of 0 runs the simulation run as fast as possible on the current hardware.
- QUAD_DYNAMICS_UPDATE: The delta time over which the dynamics of the quadcopter are updated
- CONTROLLER_DYNAMICS_UPDATE: The delta time over which the controller updates the motors (Note: Changing this value would also cause the default controller parameters to behave differently)
- QUADCOPTER(S): The parameters which define the quadcopter: initial position and orientation,length of arm, center radius, propeller size and weight.
- CONTROLLER(N)PARAMETERS: The parameters which define the controller behavior: Motor limits, Tilt limits, Yaw_Control_Limits, Throttle offset, Linear PID, Linear to Angular Scaler, Yaw_Rate_Scaler and Angular PID
- GOAL(S): The goals to loop over
- Fixed the quad dynamics to wrap angles to [-pi,pi]
- Fixed the yaw controller to determine shortest path to turn to
- Changed the yaw controller to a rate controller for better yaw control
- Added gifs
- Seperated classes into different files quadcopter.py, controller.py and gui.py
- Added an example velocity controller class and its implementation. Inherited from P2P class
- Added argparse to have a single file call all three example as command line arguments
- Added control to change the axes movements - 'w','x','a','d' along x and y axes. ('s' is used to save figure by default)
- Removed the single quadcopter class, since a single quadcopter using the multi-quad class(with keying) uses the same amount of resources(almost)
- Added a stop thread method to Quadcopter and Controller classes to isolate from main thread
- Fix the quit using 'ctrl+c'