huginn/rest.py
class WaypointResource(Resource):
    """The WaypointResource is used to ad, delete and update waypoints"""
    def __init__(self, db):
        self.db = db

    @marshal_with(request_models.waypoint)
    def get(self, name):
        """Get the waypoint's data"""
        Document = Query()

        waypoints = self.db.search(Document.type == "waypoints")[0]

        waypoint = waypoints["waypoints"].get(name)

        if waypoint is not None:
            return waypoint
        else:
            abort(404, error="waypoint doesn't exist", name=name)

    @marshal_with(request_models.waypoint)
    def post(self, name):
        """Add a new waypoint or update an existing waypoint's data"""
        waypoint = request_parsers.waypoint.parse_args()
        waypoint["name"] = name

        Document = Query()

        waypoints = self.db.search(Document.type == "waypoints")[0]

        waypoints["waypoints"][name] = waypoint

        self.db.update(waypoints, Document.type == "waypoints")

        return waypoint

    @marshal_with(request_models.waypoint)
    def delete(self, name):
        """Delete a waypoint"""
        Document = Query()

        waypoints = self.db.search(Document.type == "waypoints")[0]

        waypoint = waypoints["waypoints"].get(name)

        if waypoint is not None:
            del waypoints["waypoints"][name]
            return waypoint
        else:
            abort(404, error="waypoint doesn't exist", name=name)
huginn/rest.py
class FlightControlsResource(Resource):
    """The FlightControlsResource return the flight controls values"""

    def __init__(self, controls):
        """Create a new FlightControlsResource object

        Arguments:
        controls: A Controls object
        """
        self.controls = controls

    def get(self):
        """returns the flight controls values"""
        flight_controls_data = {
            "aileron": self.controls.aileron,
            "elevator": self.controls.elevator,
            "rudder": self.controls.rudder,
            "throttle": self.controls.throttle,
        }

        return flight_controls_data
huginn/rest.py
class InitialConditionResource(ObjectResource):
    """The InitialConditionResource object contain the simulator initial
    conditions"""

    def __init__(self, fdmexec):
        """Create a new InitialConditionResource object

        Arguments:
        fdmexec: a jsbsim FGFDMExec object
        """
        self.fdmexec = fdmexec
        self.initial_condition = InitialCondition(fdmexec)
        self.initial_condition_schema = InitialConditionSchema()

        super(InitialConditionResource, self).__init__(
            self.initial_condition,
            self.initial_condition_schema
        )

    def update_initial_conditions(self, initial_condition):
        """Update the simulator initial conditions

        Arguments:
        initial_conditions: a dictionary with the initial conditions of the
            simulator
        """
        if "latitude" in initial_condition:
            self.initial_condition.latitude = initial_condition["latitude"]

        if "longitude" in initial_condition:
            self.initial_condition.longitude = initial_condition["longitude"]

        if "airspeed" in initial_condition:
            self.initial_condition.airspeed = initial_condition["airspeed"]

        if "altitude" in initial_condition:
            self.initial_condition.altitude = initial_condition["altitude"]

        if "heading" in initial_condition:
            self.initial_condition.heading = initial_condition["heading"]

    def post(self):
        """Update the simulator condition when a POST request is executed"""
        data = request.json

        ic_schema = InitialConditionSchema()

        initial_condition = ic_schema.load(data)

        self.update_initial_conditions(initial_condition.data)

        return {"result": "ok"}
huginn/rest.py
class PitotTubeResource(Resource):
    """The PitotTubeResource returns the measurements from the pitot tube"""

    def __init__(self, pitot_tube):
        """Create a new PitotTubeResource object

        Arguments:
        pitot_tube: A PitotTube object
        """
        self.pitot_tube = pitot_tube

    def get(self):
        """Returns the pitot tube measurements"""
        pitot_tube_data = {
            "total_pressure": self.pitot_tube.pressure,
        }

        return pitot_tube_data
huginn/rest.py
class ThermometerResource(Resource):
    """The ThermometerResource class contains the measurements from the
    temperature sensor"""

    def __init__(self, thermometer):
        """Create a new ThermometerResource object

        Arguments:
        thermometer: a Thermometer object
        """
        self.thermometer = thermometer

    def get(self):
        """Returns the thermometer measurements"""
        thermometer_data = {
            "temperature": self.thermometer.temperature,
        }

        return thermometer_data
huginn/rest.py
class EngineResource(Resource):
    """The EngineResource class returns the engine data"""
    def __init__(self, engine):
        """Create a new EngineResource object

        Arguments:
        engine: An Engine object
        """
        self.engine = engine

    def get(self):
        """Returns the engine data"""
        engine_data = {
            "thrust": self.engine.thrust,
            "throttle": self.engine.throttle,
        }

        return engine_data
huginn/rest.py
class ForcesResource(ObjectResource):
    """The ForcesResource object contains the forces that act on the
    aircraft"""

    def __init__(self, fdmexec):
        """Create a new ForcesResource object

        Arguments:
        fdmexec: a jsbsim FGFDMExec object
        """
        self.fdmexec = fdmexec
        self.forces = Forces(fdmexec)
        self.forces_schema = ForcesSchema()

        super(ForcesResource, self).__init__(self.forces,
                                             self.forces_schema)
huginn/rest.py
class AircraftResource(Resource):
    """The AircraftResource returns infomration about the aircraft"""

    def __init__(self, aircraft):
        """Create a new AircraftResource object

        Arguments:
        aircraft: an Aircraft object
        """
        self.aircraft = aircraft

    def get(self):
        """Get the aircraft information"""
        return {"type": self.aircraft.type}
huginn/rest.py
class GPSResource(Resource):
    """The GPSResource returns the gps data"""

    def __init__(self, gps):
        """Create a new GPSResource object

        Arguments:
        gps: A GPS object
        """
        self.gps = gps

    def get(self):
        """Return the gps data"""
        gps_data = {
            "latitude": self.gps.latitude,
            "longitude": self.gps.longitude,
            "altitude": self.gps.altitude,
            "airspeed": self.gps.airspeed,
            "heading": self.gps.heading
        }

        return gps_data
huginn/rest.py
class AccelerationsResource(ObjectResource):
    """The AccelerationsResource object returns the fdm accelerations"""

    def __init__(self, fdmexec):
        """Create a new AccelerationsResource object

        Arguments:
        fdmexec: a jsbsim FGFDMExec object
        """
        self.fdmexec = fdmexec
        self.accelerations = Accelerations(self.fdmexec)
        self.acceleration_schema = AccelerationsSchema()

        super(AccelerationsResource, self).__init__(self.accelerations,
                                                    self.acceleration_schema)
huginn/protocols.py
class SimulatorDataProtocol(DatagramProtocol):
    """The FDMDataProtocol class is used to transmit the flight dynamics model
    data to the client"""
    def __init__(self, simulator, remote_host, port):
        self.simulator = simulator
        self.fdmexec = simulator.fdmexec
        self.aircraft = simulator.aircraft
        self.remote_host = remote_host
        self.port = port

    def _fill_gps_data(self, simulator_data):
        """Fill the gps data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        simulator_data.gps.latitude = self.aircraft.instruments.gps.latitude
        simulator_data.gps.longitude = self.aircraft.instruments.gps.longitude
        simulator_data.gps.altitude = self.aircraft.instruments.gps.altitude
        simulator_data.gps.airspeed = self.aircraft.instruments.gps.airspeed
        simulator_data.gps.heading = self.aircraft.instruments.gps.heading

    def _fill_accelerometer_data(self, simulator_data):
        """Fill the accelerometer data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        sensors = self.aircraft.sensors

        simulator_data.accelerometer.x = sensors.accelerometer.x
        simulator_data.accelerometer.y = sensors.accelerometer.y
        simulator_data.accelerometer.z = sensors.accelerometer.z

    def _fill_gyroscope_data(self, simulator_data):
        """Fill the gyroscope data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        sensors = self.aircraft.sensors

        simulator_data.gyroscope.roll_rate = sensors.gyroscope.roll_rate
        simulator_data.gyroscope.pitch_rate = sensors.gyroscope.pitch_rate
        simulator_data.gyroscope.yaw_rate = sensors.gyroscope.yaw_rate

    def _fill_thermometer_data(self, simulator_data):
        """Fill the thermometer data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        thermometer = self.aircraft.sensors.thermometer

        simulator_data.thermometer.temperature = thermometer.temperature

    def _fill_pressure_sensor_data(self, simulator_data):
        """Fill the pressure sensor data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        pressure_sensor = self.aircraft.sensors.pressure_sensor
        pitot_tube = self.aircraft.sensors.pitot_tube

        simulator_data.pressure_sensor.pressure = pressure_sensor.pressure
        simulator_data.pitot_tube.pressure = pitot_tube.pressure

    def _fill_engine_data(self, simulator_data):
        """Fill the engine data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        simulator_data.engine.thrust = self.aircraft.engine.thrust
        simulator_data.engine.throttle = self.aircraft.engine.throttle

    def _fill_aircraft_controls_data(self, simulator_data):
        """Fill the aircraft controls data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        simulator_data.controls.aileron = self.aircraft.controls.aileron
        simulator_data.controls.elevator = self.aircraft.controls.elevator
        simulator_data.controls.rudder = self.aircraft.controls.rudder
        simulator_data.controls.throttle = self.aircraft.controls.throttle

    def _fill_ins_data(self, simulator_data):
        """Fill the inertial navigation system data in the SimulatorData
        object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        ins = self.aircraft.sensors.inertial_navigation_system

        simulator_data.ins.roll = ins.roll
        simulator_data.ins.pitch = ins.pitch
        simulator_data.ins.latitude = ins.latitude
        simulator_data.ins.longitude = ins.longitude
        simulator_data.ins.altitude = ins.altitude
        simulator_data.ins.airspeed = ins.airspeed
        simulator_data.ins.heading = ins.heading

    def _fill_accelerations(self, simulator_data):
        """Fill the fdm accelerations data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        accelerations = self.simulator.fdm.accelerations

        simulator_data.accelerations.x = accelerations.x
        simulator_data.accelerations.y = accelerations.y
        simulator_data.accelerations.z = accelerations.z
        simulator_data.accelerations.p_dot = accelerations.p_dot
        simulator_data.accelerations.q_dot = accelerations.q_dot
        simulator_data.accelerations.r_dot = accelerations.r_dot
        simulator_data.accelerations.u_dot = accelerations.u_dot
        simulator_data.accelerations.v_dot = accelerations.v_dot
        simulator_data.accelerations.w_dot = accelerations.w_dot
        simulator_data.accelerations.gravity = accelerations.gravity

    def _fill_velocities(self, simulator_data):
        """Fill the fdm velocities data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        velocities = self.simulator.fdm.velocities

        simulator_data.velocities.p = velocities.p
        simulator_data.velocities.q = velocities.q
        simulator_data.velocities.r = velocities.r
        simulator_data.velocities.u = velocities.u
        simulator_data.velocities.v = velocities.v
        simulator_data.velocities.w = velocities.w
        simulator_data.velocities.true_airspeed = velocities.true_airspeed

        calibrated_airspeed = velocities.calibrated_airspeed
        simulator_data.velocities.calibrated_airspeed = calibrated_airspeed

        equivalent_airspeed = velocities.equivalent_airspeed
        simulator_data.velocities.equivalent_airspeed = equivalent_airspeed

        simulator_data.velocities.climb_rate = velocities.climb_rate
        simulator_data.velocities.ground_speed = velocities.ground_speed

    def _fill_position(self, simulator_data):
        """Fill the fdm position data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        position = self.simulator.fdm.position

        simulator_data.position.latitude = position.latitude
        simulator_data.position.longitude = position.longitude
        simulator_data.position.altitude = position.altitude
        simulator_data.position.heading = position.heading

    def _fill_orientation(self, simulator_data):
        """Fill the fdm orientation data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        orientation = self.simulator.fdm.orientation

        simulator_data.orientation.phi = orientation.phi
        simulator_data.orientation.theta = orientation.theta
        simulator_data.orientation.psi = orientation.psi

    def _fill_atmosphere(self, simulator_data):
        """Fill the fdm atmospheric data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        atmosphere = self.simulator.fdm.atmosphere

        simulator_data.atmosphere.pressure = atmosphere.pressure

        sea_level_pressure = atmosphere.sea_level_pressure
        simulator_data.atmosphere.sea_level_pressure = sea_level_pressure

        simulator_data.atmosphere.temperature = atmosphere.temperature

        sea_level_temperature = atmosphere.sea_level_temperature
        simulator_data.atmosphere.sea_level_temperature = sea_level_temperature

        simulator_data.atmosphere.density = atmosphere.density

        sea_level_density = atmosphere.sea_level_density
        simulator_data.atmosphere.sea_level_density = sea_level_density

    def _fill_forces(self, simulator_data):
        """Fill the fdm atmospheric data in the SimulatorData object

        Arguments:
        simulator_data: the protocol buffer SimulatorData object
        """
        forces = self.simulator.fdm.forces

        simulator_data.forces.x_body = forces.x_body
        simulator_data.forces.y_body = forces.y_body
        simulator_data.forces.z_body = forces.z_body
        simulator_data.forces.x_wind = forces.x_wind
        simulator_data.forces.y_wind = forces.y_wind
        simulator_data.forces.z_wind = forces.z_wind
        simulator_data.forces.x_total = forces.x_total
        simulator_data.forces.y_total = forces.y_total
        simulator_data.forces.z_total = forces.z_total

    def get_simulator_data(self):
        """Return the simulator data"""
        simulator_data = fdm_pb2.SimulatorData()

        simulator_data.time = self.fdmexec.GetSimTime()

        self._fill_gps_data(simulator_data)
        self._fill_accelerometer_data(simulator_data)
        self._fill_gyroscope_data(simulator_data)
        self._fill_thermometer_data(simulator_data)
        self._fill_pressure_sensor_data(simulator_data)
        self._fill_engine_data(simulator_data)
        self._fill_aircraft_controls_data(simulator_data)
        self._fill_ins_data(simulator_data)
        self._fill_accelerations(simulator_data)
        self._fill_velocities(simulator_data)
        self._fill_position(simulator_data)
        self._fill_orientation(simulator_data)
        self._fill_atmosphere(simulator_data)
        self._fill_forces(simulator_data)

        return simulator_data

    def send_simulator_data(self):
        """Transmit the simulator data"""
        simulator_data = self.get_simulator_data()

        datagram = simulator_data.SerializeToString()

        self.transport.write(datagram, (self.remote_host, self.port))
huginn/http.py
class SimulatorDataWebSocketFactory(WebSocketServerFactory):
    """The SimulatorDataWebSocketFactory class is a factory that creates the
    protocol objects for the simulator data transmission through web sockets"""
    def __init__(self, simulator, database, *args, **kwargs):
        WebSocketServerFactory.__init__(self, *args, **kwargs)

        self.simulator = simulator
        self.database = database
huginn/rest.py
class PressureSensorResource(Resource):
    """The PressureSensorResource class returns the pressure sensor
    measurements"""

    def __init__(self, pressure_sensor):
        """Create a new PressureSensorResource object

        Arguments:
        pressure_sensor: a PressureSensor object
        """
        self.pressure_sensor = pressure_sensor

    def get(self):
        """Returns the pressure sensor data"""
        pressure_sensor_data = {
            "static_pressure": self.pressure_sensor.pressure,
        }

        return pressure_sensor_data
huginn/rest.py
class WaypointsResource(Resource):
    """The WaypointsResource is used to retrieve all the available waypoints"""
    def __init__(self, db):
        self.db = db

    @marshal_with(request_models.waypoint)
    def get(self):
        """Get a list of the available waypoints"""
        Document = Query()

        waypoints = self.db.search(Document.type == "waypoints")[0]

        return waypoints["waypoints"].values()
huginn/rest.py
class InertialNavigationSystemResource(Resource):
    """The InertialNavigationSystemResource returns the measurements from the
    inertial navigation system"""

    def __init__(self, inertial_navigation_system):
        """Create a new InertialNavigationSystemResource object

        Arguments:
        inertial_navigation_system: An InertialNavigationSystem object
        """
        self.inertial_navigation_system = inertial_navigation_system

    def get(self):
        """Returns the ins measurements"""
        inertial_navigation_system_data = {
            "latitude": self.inertial_navigation_system.latitude,
            "longitude": self.inertial_navigation_system.longitude,
            "altitude": self.inertial_navigation_system.altitude,
            "airspeed": self.inertial_navigation_system.airspeed,
            "heading": self.inertial_navigation_system.heading,
            "roll": self.inertial_navigation_system.roll,
            "pitch": self.inertial_navigation_system.pitch,
        }

        return inertial_navigation_system_data
huginn/rest.py
class SimulatorControlResource(Resource):
    """The SimulatorControlResource provides the endpoint that is used to
    control the simulator"""

    def __init__(self, simulator):
        """Create a new SimulatorControlResource object

        Arguments:
        simulator: a Simulator object
        """
        self.simulator = simulator

    def get(self):
        """Returns the simulator state"""
        simulator_state = {
            "time": self.simulator.simulation_time,
            "dt": self.simulator.dt,
            "running": not self.simulator.is_paused(),
            "crashed": self.simulator.crashed
        }

        return simulator_state

    def execute_command(self, command, params=None):
        """Execute the simulator command

        Arguments:
        command: the command to execute
        params: the parameters of the command
        """
        if command == "reset":
            self.simulator.reset()

            response = {"result": "ok",
                        "command": command}
        elif command == "pause":
            self.simulator.pause()

            response = {"result": "ok",
                        "command": command}
        elif command == "resume":
            self.simulator.resume()

            response = {"result": "ok",
                        "command": command}
        elif command == "step":
            self.simulator.step()

            response = {"result": "ok",
                        "command": command}
        elif command == "run_for":
            if params:
                time_to_run = params["time_to_run"]
            else:
                time_to_run = None

            if not time_to_run:
                response = {"error": "no time to run provided",
                            "command": command}
            else:
                self.simulator.run_for(time_to_run)

                response = {"result": "ok",
                            "command": "run_for"}
        elif command == "start_paused":
            self.simulator.start_paused = True

            response = {"result": "ok",
                        "command": "start_paused"}
        elif command == "start_running":
            self.simulator.start_paused = False

            response = {"result": "ok",
                        "command": "start_running"}
        else:
            response = {"error": "unknown command",
                        "command": command}

        return response

    def post(self):
        """Execute a command on the simulator"""
        parser = reqparse.RequestParser()

        parser.add_argument("command", type=str, required=True)
        parser.add_argument("time_to_run", type=float)
        parser.add_argument("paused", type=bool)

        args = parser.parse_args()

        command = args.command

        params = {}

        if args.time_to_run:
            params["time_to_run"] = args.time_to_run

        if args.paused:
            params["paused"] = args.paused

        return self.execute_command(command, params)
huginn/rest.py
class VerticalSpeedIndicatorResource(ObjectResource):
    """The VerticalSpeedIndicatorResource object returns the aircraft's heading
    indicator data"""

    def __init__(self, vertical_speed_indicator):
        """Create a new VerticalSpeedIndicatorResource object

        Arguments:
        vertical_speed_indicator: a VerticalSpeedIndicator object
        """
        self.vertical_speed_indicator = vertical_speed_indicator
        self.vertical_speed_indicator_schema = VerticalSpeedIndicatorSchema()

        super(VerticalSpeedIndicatorResource, self).__init__(
            self.vertical_speed_indicator,
            self.vertical_speed_indicator_schema
        )
huginn/rest.py
class OrientationResource(ObjectResource):
    """The OrientationResource object returns the orientations of the
    aircraft"""

    def __init__(self, fdmexec):
        """Create a new OrientationResource object

        Arguments:
        fdmexec: a jsbsim FGFDMExec object
        """
        self.fdmexec = fdmexec
        self.orientation = Orientation(fdmexec)
        self.orientation_schema = OrientationSchema()

        super(OrientationResource, self).__init__(self.orientation,
                                                  self.orientation_schema)
huginn/http.py
class SimulatorDataWebSocketProtocol(WebSocketServerProtocol):
    """The SimulatorDataWebSocketProtocol class if the protocol class that
    transmits the simulator data using a web socket"""
    def onMessage(self, payload, isBinary):
        try:
            request = json.loads(payload)
        except:
            logger.exception("failed to parse websocket command")
            return

        if "command" not in request:
            logger.debug("The request doesn't contain a command field")
            return

        command = request["command"]

        if command == "flight_data":
            self.send_flight_data()
        elif command == "waypoints":
            self.send_waypoint_data()
        else:
            logger.warning("Unknown web socket command %s", command)

    def send_flight_data(self):
        """Send the fdm data"""
        fdm = self.factory.simulator.fdm

        flight_data = {
            "command": "flight_data",
            "data": {
                "roll": fdm.orientation.phi,
                "pitch": fdm.orientation.theta,
                "airspeed": fdm.velocities.true_airspeed,
                "latitude": fdm.position.latitude,
                "longitude": fdm.position.longitude,
                "altitude": fdm.position.altitude,
                "heading": fdm.position.heading,
                "climb_rate": fdm.velocities.climb_rate
            },
        }

        payload = json.dumps(flight_data).encode("utf8")

        self.sendMessage(payload, False)

    def send_waypoint_data(self):
        """Send the waypoint information"""
        Document = Query()

        waypoints = self.factory.database.search(
            Document.type == "waypoints")[0]

        response = {
            "command": "waypoints",
            "data": waypoints["waypoints"].values()
        }

        payload = json.dumps(response).encode("utf8")

        self.sendMessage(payload, False)
huginn/rest.py
class AirspeedIndicatorResource(ObjectResource):
    """The AirspeedIndicatorResource object returns the aircraft's true
    airspeed"""

    def __init__(self, airspeed_indicator):
        """Create a new AirspeedindicatorResource object

        Arguments:
        airspeed_indicator: an AirspeedIndicator object
        """
        self.airspeed_indicator = airspeed_indicator
        self.airspeed_indicator_schema = AirspeedIndicatorSchema()

        super(AirspeedIndicatorResource, self).__init__(
            self.airspeed_indicator,
            self.airspeed_indicator_schema
        )
huginn/rest.py
class AccelerometerResource(Resource):
    """The AccelerometerResource returns the accelerometer measurements"""

    def __init__(self, accelerometer):
        """Create a new AccelerometerResource object

        Arguments:
        accelerometer: an Accelerometer object
        """
        self.accelerometer = accelerometer

    def get(self):
        """Returns the accelerometer measurements"""
        accelerometer_data = {
            "x": self.accelerometer.x,
            "y": self.accelerometer.y,
            "z": self.accelerometer.z,
        }

        return accelerometer_data
huginn/rest.py
class PositionResource(ObjectResource):
    """The PositionResource object contain the aircraft position data"""

    def __init__(self, fdmexec):
        """Create a new PositionResource object

        Arguments:
        fdmexec: a jsbsim FGFDMExec object
        """
        self.fdmexec = fdmexec
        self.position = Position(fdmexec)
        self.position_schema = PositionSchema()

        super(PositionResource, self).__init__(
            self.position,
            self.position_schema
        )
huginn/rest.py
class GyroscopeResource(Resource):
    """The GyroscopeResource returns the data from the gyroscope sensor"""

    def __init__(self, gyroscope):
        """Create a new GyroscopeResource object

        Arguments:
        gyroscope: A Gyroscope object
        """
        self.gyroscope = gyroscope

    def get(self):
        """Returns the gyroscope measurements"""
        gyroscope_data = {
            "roll_rate": self.gyroscope.roll_rate,
            "pitch_rate": self.gyroscope.pitch_rate,
            "yaw_rate": self.gyroscope.yaw_rate
        }

        return gyroscope_data
huginn/rest.py
class AtmosphereResource(ObjectResource):
    """The AtmosphereResource object return the fdm atmospheric data"""

    def __init__(self, fdmexec):
        """Create a new AtmosphereResource object

        Arguments:
        fdmexec: a jsbsim FGFDMExec object
        """
        self.fdmexec = fdmexec
        self.atmosphere = Atmosphere(fdmexec)
        self.atmosphere_schema = AtmosphereShema()

        super(AtmosphereResource, self).__init__(self.atmosphere,
                                                 self.atmosphere_schema)
huginn/rest.py
class AltimeterResource(ObjectResource):
    """The AltimeterResource object returns the aircraft's altimeter data"""

    def __init__(self, altimeter):
        """Create a new AltimeterResource object

        Arguments:
        altimeter: an Altimeter object
        """
        self.altimeter = altimeter
        self.altimeter_schema = AltimeterSchema()

        super(AltimeterResource, self).__init__(
            self.altimeter,
            self.altimeter_schema
        )
huginn/rest.py
class FDMResource(Resource):
    """The FDMResource will return the data from the flight dynamics model"""

    def __init__(self, fdm, aircraft):
        """Create a new FDMResource object

        Arguments:
        fdm: an FDM object
        aircraft: an aircraft object
        """
        self.fdm = fdm
        self.aircraft = aircraft

    def get(self):
        """Get the fdm data"""
        sensors = self.aircraft.sensors

        flight_data = {
            "time": self.fdm.fdmexec.GetSimTime(),
            "dt": self.fdm.fdmexec.GetDeltaT(),
            "latitude": self.fdm.position.latitude,
            "longitude": self.fdm.position.longitude,
            "altitude": self.fdm.position.altitude,
            "airspeed": self.fdm.velocities.true_airspeed,
            "heading": self.fdm.orientation.psi,
            "x_acceleration": self.fdm.accelerations.x,
            "y_acceleration": self.fdm.accelerations.y,
            "z_acceleration": self.fdm.accelerations.z,
            "roll_rate": self.fdm.velocities.p,
            "pitch_rate": self.fdm.velocities.q,
            "yaw_rate": self.fdm.velocities.r,
            "temperature": self.fdm.atmosphere.temperature,
            "static_pressure": self.fdm.atmosphere.pressure,
            "total_pressure": sensors.pitot_tube.true_pressure,
            "roll": self.fdm.orientation.phi,
            "pitch": self.fdm.orientation.theta,
            "climb_rate": self.fdm.velocities.climb_rate
        }

        return flight_data
huginn/rest.py
class HeadingIndicatorResource(ObjectResource):
    """The HeadingIndicatorResource object returns the aircraft's heading
    indicator data"""

    def __init__(self, heading_indicator):
        """Create a new HeadingIndicatorResource object

        Arguments:
        heading_indicator: a HeadingIndicator object
        """
        self.heading_indicator = heading_indicator
        self.heading_indicator_schema = HeadingIndicatorSchema()

        super(HeadingIndicatorResource, self).__init__(
            self.heading_indicator,
            self.heading_indicator_schema
        )
huginn/rest.py
class AttitudeIndicatorResource(ObjectResource):
    """The AttitudeIndicatorResource object returns the aircraft's attitude
    indicator data"""

    def __init__(self, attitude_indicator):
        """Create a new AttitudeIndicatorResource object

        Arguments:
        attitude_indicator: an AttitudeIndicator object
        """
        self.attitude_indicator = attitude_indicator
        self.attitude_indicator_schema = AttitudeIndicatorSchema()

        super(AttitudeIndicatorResource, self).__init__(
            self.attitude_indicator,
            self.attitude_indicator_schema
        )
huginn/protocols.py
class ControlsProtocol(DatagramProtocol):
    """The ControlsProtocol is used to receive and update tha aircraft's
    controls"""
    def __init__(self, fdmexec):
        self.fdmexec = fdmexec

    def update_aircraft_controls(self, aileron, elevator, rudder, throttle):
        """Set the new aircraft controls values"""
        if aileron > 1.0:
            aileron = 1.0
        elif aileron < -1.0:
            aileron = -1.0

        self.fdmexec.GetFCS().SetDaCmd(aileron)

        if elevator > 1.0:
            elevator = 1.0
        elif elevator < -1.0:
            elevator = -1.0

        self.fdmexec.GetFCS().SetDeCmd(elevator)

        if rudder > 1.0:
            rudder = 1.0
        elif rudder < -1.0:
            rudder = -1.0

        self.fdmexec.GetFCS().SetDrCmd(rudder)

        if throttle > 1.0:
            throttle = 1.0
        elif throttle < 0.0:
            throttle = 0.0

        for i in range(self.fdmexec.GetPropulsion().GetNumEngines()):
            self.fdmexec.GetFCS().SetThrottleCmd(i, throttle)

    def datagramReceived(self, datagram, addr):
        controls = fdm_pb2.Controls()

        try:
            controls.ParseFromString(datagram)
        except DecodeError:
            logger.exception("Failed to parse control data")
            print("Failed to parse control data")
            return

        self.update_aircraft_controls(controls.aileron,
                                      controls.elevator,
                                      controls.rudder,
                                      controls.throttle)
huginn/rest.py
class VelocitiesResource(ObjectResource):
    """The VelocitiesResource object returns the fdm velocities"""

    def __init__(self, fdmexec):
        """Create a new VelocitiesResource object

        Arguments:
        fdmexec: a jsbsim FGFDMExec object
        """
        self.fdmexec = fdmexec
        self.velocities = Velocities(self.fdmexec)
        self.velocities_schema = VelocitiesSchema()

        super(VelocitiesResource, self).__init__(self.velocities,
                                                 self.velocities_schema)


Question: import logging
from twisted.web import server
from twisted.internet.task import LoopingCall
from twisted.web.wsgi import WSGIResource
from flask import Flask, render_template
from flask_restful import Api
from huginn.protocols import ControlsProtocol, SimulatorDataProtocol
from huginn.http import (SimulatorDataWebSocketFactory,
                         SimulatorDataWebSocketProtocol)
from huginn.rest import (FDMResource, AircraftResource, GPSResource,
                         AccelerometerResource, GyroscopeResource,
                         ThermometerResource, PressureSensorResource,
                         PitotTubeResource, InertialNavigationSystemResource,
                         EngineResource, FlightControlsResource,
                         SimulatorControlResource, AccelerationsResource,
                         VelocitiesResource, OrientationResource,
                         AtmosphereResource, ForcesResource,
                         InitialConditionResource, PositionResource,
                         AirspeedIndicatorResource, AltimeterResource,
                         AttitudeIndicatorResource, HeadingIndicatorResource,
                         VerticalSpeedIndicatorResource, WaypointResource,
                         WaypointsResource)
    fdmexec: an JSBSim FGFDMExec object
    port: the ports to listen for the flight control data
    """
    logger.debug("Starting aircraft controls server at port %d", port)

    controls_protocol = ControlsProtocol(fdmexec)

    reactor.listenUDP(port, controls_protocol)


def initialize_simulator_data_server(reactor, simulator, clients):
    """Initialize the simulator data server

    Arguments:
    reactor: a Twisted reactor to use
    simulator: a Simulator object
    clients: a list of (address, port) tuples of the listening clients
    """
    for address, port, update_rate in clients:
        logger.debug("Sending fdm data to %s:%d every %f seconds",
                     address, port, update_rate)

        simulator_data_protocol = SimulatorDataProtocol(simulator,
                                                        address,
                                                        port)

        reactor.listenUDP(0, simulator_data_protocol)

        simulator_data_updater = LoopingCall(
            simulator_data_protocol.send_simulator_data)

        simulator_data_updater.start(update_rate)


def initialize_websocket_server(reactor, simulator, host, port, database):
    """Initialize the web socket server

    Arguments:
    reactor: a twisted reactor object
    simulator: an Simulator object
    host: the server host
    port: the port to listen to
    database: the database that contains the simulator data
    """
    logger.debug("The websocket interface runs on %s:%d", host, port)

    factory = SimulatorDataWebSocketFactory(
        simulator,
        database,
        "ws://%s:%d" % (host, port),
    )

    factory.protocol = SimulatorDataWebSocketProtocol

    reactor.listenTCP(port, factory)


def _add_fdm_resources(api, fdm, aircraft):
    api.add_resource(FDMResource, "/fdm",
                     resource_class_args=(fdm, aircraft))

    api.add_resource(AccelerationsResource, "/fdm/accelerations",
                     resource_class_args=(fdm.fdmexec,))

    api.add_resource(VelocitiesResource, "/fdm/velocities",
                     resource_class_args=(fdm.fdmexec,))

    api.add_resource(OrientationResource, "/fdm/orientation",
                     resource_class_args=(fdm.fdmexec,))

    api.add_resource(AtmosphereResource, "/fdm/atmosphere",
                     resource_class_args=(fdm.fdmexec,))

    api.add_resource(ForcesResource, "/fdm/forces",
                     resource_class_args=(fdm.fdmexec,))

    api.add_resource(InitialConditionResource, "/fdm/initial_condition",
                     resource_class_args=(fdm.fdmexec,))

    api.add_resource(PositionResource, "/fdm/position",
                     resource_class_args=(fdm.fdmexec,))


def _add_instrument_resources(api, instruments):
    api.add_resource(GPSResource, "/aircraft/instruments/gps",
                     resource_class_args=(instruments.gps,))

    api.add_resource(
        AirspeedIndicatorResource,
        "/aircraft/instruments/airspeed_indicator",
        resource_class_args=(instruments.airspeed_indicator,)
    )

    api.add_resource(
        AltimeterResource,
        "/aircraft/instruments/altimeter",
        resource_class_args=(instruments.altimeter,)
    )

    api.add_resource(
        AttitudeIndicatorResource,
        "/aircraft/instruments/attitude_indicator",
        resource_class_args=(instruments.attitude_indicator,)
    )

    api.add_resource(
        HeadingIndicatorResource,
        "/aircraft/instruments/heading_indicator",
        resource_class_args=(instruments.heading_indicator,)
    )

    api.add_resource(
        VerticalSpeedIndicatorResource,
        "/aircraft/instruments/vertical_speed_indicator",
        resource_class_args=(instruments.vertical_speed_indicator,)
    )


def _add_sensor_resources(api, sensors):
    api.add_resource(

Answer:         AccelerometerResource,