Skip to content

wangdongnwpu/Hackflight

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hackflight is a simple, platform-independent, header-only C++ toolkit for building multirotor flight controllers. It is geared toward people like me who want to tinker with flight-control firmware, and use it to teach students about ideas like inertial measurement and PID tuning. If you are in the 99% percent of users who just want to get your vehicle flying without getting into firmware hacking, I recommend Cleanflight (great for getting started when you're on a budget) or the Ardupilot system (for sophisticated mission planning with waypoint navigation and the like). In addition to big user communities and loads of great features, these platforms have safety mechanisms that Hackflight lacks, which will help avoid injury to you and damage to your vehicle.

Hackflight is current working on the following platforms:

  • TinyPICO

  • Ladybug brushed flight controller from Tlera Corp.

  • SuperFly Hackable ESP8266 Flight Controller from Pesky Products

  • Butterfly DIY brushless flight controller (components from from Tlera Corp. and Pesky Products)

  • MulticopterSim flight simulator based on UnrealEngine4

By supporting floating-point operations, these platforms allow us to write simpler code based on standard units:

  • Distances in meters
  • Time in seconds
  • Quaternions in the interval [-1,+1]
  • Euler angles in radians
  • Accelerometer values in Gs
  • Barometric pressure in Pascals
  • Stick demands in the interval [-1,+1]
  • Motor demands in [0,1]

Thanks to some help from Sytelus, the core Hackflight firmware adheres to standard practices for C++, notably, short, simple methods and minimal use of compiler macros like #ifdef that can make it difficult to follow what the code is doing.

Because a DIY multirotor build typically involves choosing a microcontroller board, inertial measurement unit (IMU), radio receiver, model (airframe), motors, and PID control settings, Hackflight provides a separate C++ class to support each of these components:

  • The Board class specifies an abstract (pure virtual) getTime() method that you must implement for a particular microcontroller or simulator.
  • The IMU class specifies an abstract (pure virtual) getQuaternion() and getGyrometer() method that you must implement for a particular IMU.
  • The Receiver class performs basic functions associated with R/C control (tracking stick positions, checking switches) and specifies a set of abstract methods that you implement for a particular receiver (reading channels values).
  • The Mixer class is an abstract class that can be subclassed for various motor configurations (QuadX, Hexacopter, Tricopter, etc.). The QuadXCF (quad-X using Cleanflight numbering conventions) and QuadXAP (quad-X using ArduPilot numbering conventions) subclasses are already implemented.
  • The Motor class supports different kinds of motors (brushed, brushless).
  • The PidController class provides a constructor where you specify the PID values appropriate for your model (see PID Controllers discussion below).

Because it is useful to get some visual feedback on things like vehicle orientation and RC receiver channel values, we also provide a very simple “Ground Control Station” (GCS) program. that allows you to connect to the board and see what's going on. Windows users can run this program directly: just download this zipfile, unzip the file, open the folder, and double-click on hackflight.exe. Others can run the hackflight.py Python script in the extras/gcs/python folder. To run the Python script you'll need to install MSPPG, a parser generator for the Multiwii Serial Protocol (MSP) messages used by the firmware. Follow the directions in that folder to install MSPPG for Python.

To support working with new new sensors and PID control algorithms, the Hackflight C++ class provides two methods: addSensor and addPidController. For an example of how to use these methods, take a look at this sketch, which uses the VL53L1X long-range proximity sensor to provide altitude hold.

To get started with Hackflight, take a look at the build wiki. To understand the principles behind the software, contniue reading.

Design Principles

There are two basic data types in Hackflight: state and demands. For anyone who's studied Kalman filtering, the state will be familiar: it is the set of values that define the state of the vehicle at a given time (altitude, orientation, angular velocity, ...), which gets modified by a set of sensors (gyrometer, accelerometer, barometer, rangefinder, ...). Once the state has been determined, it is used by a set of PID controllers to modify the demands (throttle, roll, pitch, yaw) received by the R/C receiver or other control device. Then the demands are then sent to the mixer, which determines the values to be sent to each motor. The motors spin the propellers, which in turn modifies the state of the vehicle:

Sensors

As discussed above, Hackflight requires a bare minimum of two sensor readings: quaternion and gyrometer. Technically, the quaternion is more properly part of the vehicle state, but because of the availability of “hardware quaternion” data from modern sensors like the EM7180 SENtral Sensor Fusion Solution. we find it convenient to treat the quaternion as a sensor reading. For inertial measurement units (IMUs) like the MPU9250 that do not deliver a hardware quaternion, Hackflight provides a QuaternionFilter class that can be used to compute the quaternion using your microcontroller.

If you're mathematically-minded, you can think of a sensor as a function from states to states: Sensor: StateState

To provide access to other popular surface-mount sensors that you may wish to read, Hackflight also has classes to support accelerometers, magnetometers, and barometers. Together with the quaternion and gyrometer, these are all sub-classes of the SurfaceMountSensor class, which is in turn a sub-class of the Sensor class. Each surface-mount sensor accesses the appropriate virtual method of the Board class (getQuaternion(), getGyrometer(), ...). The Sensor class is an abstract (virtual) class (a.k.a. interface) specifying two methods that any sensor must implement: (1) reporting whether the sensor is ready to deliver new data; (2) modifying the vehicle state. By requiring each sensor to report its readiness, we can avoid the need to write a separate timing loop for each sensor in the main loop code.

To implement additional sensors, you can directly sub-class the Sensor class, as we've done with the Rangefinder class that we use to support the VL53L1 time-of-flight rangefinder in an example sketch. Once you've implemented the sub-class(es) for a new sensor, you can call Hackflight::addSensor() to ensure that the sensor code will be called by the checkOptionalSensors method.

PID Controllers

Like sensors, PID controllers in Hackflight are subclasses of an abstract class, whose modifyDemands() method takes the current state and demands, and modifies the demands based on the state. (This class also provides an optional shouldFlashLed() method, to help you see when the PID controller is active.)

As with sensors, you can sub-class the PidController class and call Hackflight::addPidController() to ensure that your PID controller is called in the Hackflight::runPidControllers() method. The addPidController() method allows you to to specify the auxiliary-switch state (aux state) in which the specified PID controller will be active. For example, you can specify that a Rate controller will be active in aux state 0 and a Level controller in aux state 1. If you leave out the aux state, the PID controller will be active in all states.

Note these two important points about PID controllers in Hackflight:

  1. A PID controller is not the same as a flight mode. For example, so-called Acro mode requires a PID controller based on angular velocity (a.k.a. rate, computed from the gyrometer) for each of the three angles (roll, pitch yaw). So-called Stabilize mode requires these three angular-velocity controllers, plus a PID controller based on angle (computed from the quaternion) for the roll and pitch axes. To support this arrangement in Hackflight, PID controllers for aux state 0 will also run in aux states 1 and 2, and PID controllers for aux state 1 will also run in aux state 2.

  2. It matters in which order you add PID controllers, because the output of one PID controller is the input to the next. For example, to get Stabilize mode, you want the Level controller to go first, setting the desired pitch/roll angles, and the Rate controller to go next, to control the rate at which the desired angle will be reached.

If you're mathematically-minded, you can think of a PID Controller as a function from a (State, Demands) pair to Demands:
PID Controller: State × DemandsDemands

Board classes

As described above, the Board class specifies a set of abstract methods that you must implement for a particular flight controller or simulator. The figure below shows the class hierarchy for currently implemented and tested boards. As the figure shows, Hackflight makes extensive use of C++ inheritance to minimize the amount of redundant code among these classes. Here is a brief description of each member of the Board class hierarchy:

  • Board: Ancestor class for all boards, real and simulated

  • RealBoard: Ancestor class for real (physical) boards

  • SimulatedBoard: Anything other than a real board; for example, the SimBoard class used in MulticopterSim.

  • ArduinoBoard: Ancestor class for Arduino-compatible boards

  • MockBoard: Parent class for Arduino development boards; enables algorithm, sensor, and receiver prototyping

HackflightLite

Hackflight can also be used to add functionality to an existing Ready-to-Fly (RTF) multicopter. In this flavor of Hackflight, you rely on the IMU, stabilization PIDs, and mixer on the off-the-shelf flight controller on your 'copter. Instead of specifying a mixer and motors, you specify an RXProxy (receiver proxy) object that will send receiver signals into your controller, based on the demands sent by the receiver connected to your Arduino board, plus whatever sensors (rangefinder, optical flow) and PID controllers (altitude hold, position hold), you've added. A simple example is provided in this sketch, which uses the Ladybug development board from Tlera Corp., plus a DSMX receiver, and generates SBUS signals as input to the flight-control board.

About

Multirotor flight-control toolkit for makers

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 35.5%
  • Java 27.4%
  • Makefile 20.7%
  • Python 15.0%
  • CMake 1.1%
  • C 0.2%
  • Shell 0.1%