packages feed

casa-reoc-0.1.0.0: examples/src/ReOC/Example/Aircraft.hs

{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wall #-}

{- | Types of RPA that the examples operate, with their type-specific
procedures, as unfilled forms filled in with their optics. The makes, models
and weights are of real RPA; the procedures are illustrative, and an operator
writes its own from the manufacturer's current manual.
-}
module ReOC.Example.Aircraft (
  djiMavic3Pro,
  djiMavic3Thermal,
  djiMavic3Multispectral,
  djiMavic3Classic,
  djiMatrice30T,
  djiMatrice350RTK,
  wingtraOneGenII,
  agEagleEBeeX,
  operatedType,
  aircraft,
  equipment,
) where

import Control.Lens ((&), (.~), (?~))
import Data.Text (Text)
import ReOC.Model

-- | A type of RPA that the operator operates, with each RPA of that type.
operatedType :: UnfilledRPAType -> [UnfilledAircraft] -> UnfilledOperatedType
operatedType t rpa =
  mkUnfilledOperatedType
    & rpaType .~ t
    & airframes .~ rpa

-- | An RPA with its serial number and associated equipment.
aircraft :: Text -> [UnfilledEquipment] -> UnfilledAircraft
aircraft serial things =
  mkUnfilledAircraft
    & serialNumber ?~ serial
    & associatedEquipment .~ things

-- | An item of equipment with its serial number.
equipment :: Text -> Text -> UnfilledEquipment
equipment description serial =
  mkUnfilledEquipment
    & equipmentDescription ?~ description
    & serialNumber ?~ serial

-- An emergency action: the situation, what the RPA does, and the remote pilot's further steps.
emergencyAction :: Text -> Text -> [Text] -> UnfilledEmergencyAction
emergencyAction s r steps =
  mkUnfilledEmergencyAction
    & situation ?~ s
    & response ?~ r
    & actionSteps .~ steps

-- A multirotor of DJI, with the inspection items, before-flight requirements, battery warnings and emergency actions
-- that DJI's multirotors share.
djiMultirotor :: Text -> Text -> Text -> UnfilledRPAType
djiMultirotor model short manual =
  mkUnfilledRPAType
    & rpaMake ?~ "DJI"
    & rpaModel ?~ model
    & shortName ?~ short
    & category ?~ Multirotor
    & userManual ?~ manual
    & transponderCarriage ?~ NoTransponder
    & flightTermination ?~ NoFlightTerminationSystem
    & inspectionItems .~ djiInspectionItems
    & beforeFlight .~ djiBeforeFlight
    & batteryWarnings ?~ "The RPA warns when the remaining battery is only enough to return home, returns home automatically unless the RP cancels it, and lands automatically at critical low battery."
    & emergencyActions .~ djiEmergencyActions

-- The inspection items of a DJI multirotor.
djiInspectionItems :: [Text]
djiInspectionItems =
  [ "the airframe and its arms, including the folding joints and locks"
  , "motors, by turning each by hand to check for roughness"
  , "propellers and propeller mounts"
  , "gimbal, camera and vibration dampers"
  , "vision and infrared sensors"
  , "batteries (cycle count, cell voltage balance, swelling and damage to the case or terminals)"
  , "remote controller, its antennas and its charging equipment"
  , "firmware versions of the RPA, remote controller and batteries"
  ]

-- The before-flight requirements of a DJI multirotor.
djiBeforeFlight :: [Text]
djiBeforeFlight =
  [ "Set the RTH altitude so that the RPA will clear every obstacle between the operating area and the home point, and confirm that the home point has been recorded before take-off."
  , "Confirm that the signal-lost action is set to Return to Home."
  , "Check the compass and IMU status in DJI Pilot or DJI Fly, and calibrate the compass if the app asks for it, away from metal structures and vehicles."
  ]

-- The emergency actions of a DJI multirotor.
djiEmergencyActions :: [UnfilledEmergencyAction]
djiEmergencyActions =
  [ emergencyAction
      "Loss of command link"
      "the RPA performs its signal-lost action, Return to Home, climbing to the RTH altitude and flying to the home point. The RP must:"
      [ "keep visual contact with the RPA and move to improve the link"
      , "when the link is restored, cancel RTH and take control if the return path or landing point is unsafe"
      ]
  , emergencyAction
      "Critical low battery landing"
      "the RPA descends and lands where it is. The RP must use the throttle and controls to move the RPA, as it descends, to the nearest place clear of people and obstacles."
      []
  , emergencyAction
      "Loss of GNSS"
      "the RPA changes to ATTI mode, does not hold its position and drifts with the wind. The RP must fly the RPA manually by visual reference, keep it clear of obstacles and people, and land as soon as practicable."
      []
  , emergencyAction
      "Compass or IMU error in flight"
      "the app warns of the error and the RPA may change to ATTI mode. The RP must fly the RPA manually away from metal structures and land as soon as practicable."
      []
  ]

-- | The DJI Mavic 3 Pro, for aerial photography and videography.
djiMavic3Pro :: UnfilledRPAType
djiMavic3Pro =
  djiMultirotor "Mavic 3 Pro" "DJI Mavic 3 Pro" "DJI Mavic 3 Pro User Manual"
    & maximumGrossWeight ?~ 958

-- | The DJI Mavic 3 Thermal, for close visual and thermal inspection.
djiMavic3Thermal :: UnfilledRPAType
djiMavic3Thermal =
  djiMultirotor "Mavic 3 Thermal" "DJI Mavic 3T" "DJI Mavic 3 Enterprise Series User Manual"
    & maximumGrossWeight ?~ 1050

-- | The DJI Mavic 3 Multispectral, for crop and pasture surveys.
djiMavic3Multispectral :: UnfilledRPAType
djiMavic3Multispectral =
  djiMultirotor "Mavic 3 Multispectral" "DJI Mavic 3M" "DJI Mavic 3 Multispectral User Manual"
    & maximumGrossWeight ?~ 1050
    & inspectionItems .~ djiInspectionItems <> ["the sunlight sensor on top of the RPA, which must be clean and unobstructed"]
    & beforeFlight
      .~ djiBeforeFlight
        <> [ "Before a mapping mission, check the mission altitude, overlap and boundary in DJI Pilot 2 against the site plan, and that the mission stays inside the operating area."
           , "Set the action on completion of the mission to Return to Home, and the action on loss of signal to continue the mission only where the whole mission is within VLOS."
           ]

-- | The DJI Mavic 3 Classic, a training RPA for multirotor RePL courses.
djiMavic3Classic :: UnfilledRPAType
djiMavic3Classic =
  djiMultirotor "Mavic 3 Classic" "DJI Mavic 3 Classic" "DJI Mavic 3 Classic User Manual"
    & maximumGrossWeight ?~ 895
    & beforeFlight
      .~ djiBeforeFlight
        <> ["For a training flight, the instructor confirms that obstacle avoidance is set for the exercise, and briefs the student on when the instructor will take control."]

-- | The DJI Matrice 30T, for inspection, and as a training RPA for multirotor RePL courses.
djiMatrice30T :: UnfilledRPAType
djiMatrice30T =
  djiMultirotor "Matrice 30T" "DJI Matrice 30T" "DJI Matrice 30 Series User Manual"
    & maximumGrossWeight ?~ 3998
    & beforeFlight
      .~ djiBeforeFlight
        <> ["Check that both TB30 batteries are fitted and locked, and that their charge differs by no more than the manual allows."]

-- | The DJI Matrice 350 RTK, a medium multirotor for inspection and survey payloads.
djiMatrice350RTK :: UnfilledRPAType
djiMatrice350RTK =
  djiMultirotor "Matrice 350 RTK" "DJI M350 RTK" "DJI Matrice 350 RTK User Manual"
    & maximumGrossWeight ?~ 9200
    & inspectionItems
      .~ djiInspectionItems
        <> [ "the payload mount (DJI SkyPort) and the payload, which must be locked"
           , "the RTK module and its antennas"
           ]
    & beforeFlight
      .~ djiBeforeFlight
        <> [ "Check that both TB65 batteries are fitted and locked, and that the payload is secure in its mount."
           , "Where RTK positioning is used, confirm an RTK FIX before take-off. Do not rely on RTK for separation from obstacles."
           , "Check AirSense (ADS-B In) is enabled, and respond to its warnings of crewed aircraft as for any other conflicting traffic."
           ]
    & emergencyActions
      .~ djiEmergencyActions
        <> [ emergencyAction
              "Loss of a motor or propeller"
              "the RPA may not hold its height or heading. The RP must fly the RPA away from people, descend and land immediately, and treat the RPA as unserviceable until the MC has inspected it."
              []
           ]

-- | The WingtraOne GEN II, a VTOL tail-sitter for mapping.
wingtraOneGenII :: UnfilledRPAType
wingtraOneGenII =
  mkUnfilledRPAType
    & rpaMake ?~ "Wingtra"
    & rpaModel ?~ "WingtraOne GEN II"
    & shortName ?~ "WingtraOne GEN II"
    & category ?~ PoweredLift
    & maximumGrossWeight ?~ 4800
    & userManual ?~ "WingtraOne GEN II user manual and the WingtraHub documentation"
    & transponderCarriage ?~ NoTransponder
    & flightTermination ?~ NoFlightTerminationSystem
    & inspectionItems
      .~ [ "the fuselage, wings and winglets, for cracks and delamination"
         , "motors, propellers and propeller retainers"
         , "elevons and their servos, by moving each through its full range"
         , "the pitot tube, which must be clear"
         , "the payload bay, the camera and its lens"
         , "batteries (cycle count, cell voltage balance, swelling and damage)"
         , "the tablet, telemetry radio and their charging equipment"
         ]
    & beforeFlight
      .~ [ "Plan the mission in WingtraHub, check its altitude, its boundary and the take-off and landing point against the site plan, and confirm that the whole flight path stays within VLOS."
         , "Choose a take-off and landing point clear of obstacles by at least the distance the manual requires, and into wind."
         , "Complete the WingtraHub pre-flight checks, including the airspeed sensor check, before every flight."
         ]
    & batteryWarnings ?~ "WingtraHub warns of low battery and the RPA returns to its landing point automatically when the remaining battery is only enough to return and land."
    & emergencyActions
      .~ [ emergencyAction
            "Loss of command link"
            "the RPA continues its mission and then returns to land at its home point. The RP must keep visual contact with the RPA and, if the link is not restored and the RPA is approaching people or obstacles, prepare to keep people clear of the landing point."
            []
         , emergencyAction
            "Strong wind on landing"
            "the RPA may drift during its vertical descent. The RP must command the RPA to hover and reposition it, or abort the landing and land at the alternative landing point."
            []
         , emergencyAction
            "Airspeed sensor failure"
            "WingtraHub warns of the failure. The RP must command the RPA to return home and land, and treat it as unserviceable until the MC has inspected it."
            []
         ]

-- | The AgEagle eBee X, a fixed-wing mapping RPA, launched by hand.
agEagleEBeeX :: UnfilledRPAType
agEagleEBeeX =
  mkUnfilledRPAType
    & rpaMake ?~ "AgEagle"
    & rpaModel ?~ "eBee X"
    & shortName ?~ "AgEagle eBee X"
    & category ?~ Aeroplane
    & maximumGrossWeight ?~ 1600
    & userManual ?~ "eBee X Drone User Manual and the eMotion documentation"
    & transponderCarriage ?~ NoTransponder
    & flightTermination ?~ NoFlightTerminationSystem
    & inspectionItems
      .~ [ "the wing, its joints and the central body, for cracks and dents"
         , "the propeller and the motor"
         , "elevons and their servos"
         , "the pitot tube, which must be clear"
         , "the camera and its lens"
         , "batteries (cycle count, cell voltage balance, swelling and damage)"
         , "the ground modem, laptop and their charging equipment"
         ]
    & beforeFlight
      .~ [ "Plan the mission in eMotion, and set the home waypoint, the landing sector and the minimum and maximum altitudes, so that the RPA stays within the operating area, below 400 ft AGL and within VLOS."
         , "Choose a landing area of at least the size the manual requires, clear of obstacles and people, on a heading into wind."
         , "Complete the eMotion pre-flight checklist, including the airspeed calibration, before every flight."
         ]
    & batteryWarnings ?~ "eMotion warns of low battery, and the RPA returns home and lands when the remaining battery is only enough to do so."
    & emergencyActions
      .~ [ emergencyAction
            "Loss of command link"
            "the RPA continues its mission for the time set in eMotion, then returns to the home waypoint and lands. The RP must keep visual contact with the RPA and keep people clear of the landing area."
            []
         , emergencyAction
            "Landing area blocked"
            "the RP must abort the landing in eMotion, so that the RPA climbs and circles, and land when the area is clear or at the alternative landing area."
            []
         , emergencyAction
            "Uncontrolled flight"
            "the RP must command an emergency landing in eMotion, which stops the motor so that the RPA glides to the ground near its position."
            []
         ]