At the end of 2015, our UAV research lab at the French Civil Aviation University took part to an atmospheric research project with Meteo-France (CNRS-GAME and ENM) teams at the Atmospheric Research Center of Lannemezan (in the south of France).

This project, named VOLTIGE,  aimed at studying the formation of cloud and fog events, with simultaneous measurements through multi-UAV flights. One of the planes is measuring the turbulence near the ground, a second plane is flying above the cloud or the fog with a radiation sensor and the last one is making a vertical profile of temperature, pressure and humidity up to 1500 meters AGL.

All the planes were controlled by Paparazzi UAV Apogee boards, with on-board logging on SD cards and navigation patterns triggered by sensors readings.

The video of the flights is finally on-line.


Original posts are here: https://blog.paparazziuav.org/2015/12/04/multi-uav-flights-for-simultaneous-meteorological-measurements/ and here: https://blog.paparazziuav.org/2017/01/18/multi-uav-scientific-flights-video/

E-mail me when people leave their comments –

You need to be a member of diydrones to add comments!

Join diydrones


  • @Marc Dornan,

    as Gautier already said, the KroozSD board has an onboard MAX7456 osd which works with the corresponding software module under Paparazzi. It has rather basic functionality, but, as you said, the Paparazzi project is pretty easy to get familiar with.

  • There is a module to control a max7456 (http://docs.paparazziuav.org/latest/module__osd_max7456.html) which is part of the KroozSD board (http://wiki.paparazziuav.org/wiki/KroozSD), but I have never used it myself.

    Paparazzi UAS: osd_max7456 module
  • Thanks for the info guys. Will be giving thus a whirl. One last question. Is there an OSD for Paparazzi?
  • Hello Marc,

    As Hector and Rich already told you, the flight plan principle of Paparazzi is rather different than other UAV systems. It is based on a scripting language with basic navigation instruction, plus for and while loops, conditional jumps and so on (which makes it Turing complete actually). Our waypoints are not seen as elements of a trajectory or triggers for actions, but anchors for the navigation patterns. So even if the list is fixed at the beginning, you can reuse them and move them, so it is not really a limitation in the end. In addition to the basic features, you can also write your own patterns and directly call them from the flight plan (see http://docs.paparazziuav.org/latest/onboard_modules.html#modules_ca... for examples).

    The GUI tool for the flight plan is pretty basic but it is useful for beginners as it provides the list of possible instructions with right clicks. I must say that when you get use to Paparazzi flight plans it is much faster to edit the xml file by hand, except for placing the waypoints on the map.

    In any case, if you decide to give a try to Paparazzi, we have a few tutorials on youtube (https://www.youtube.com/c/PaparazziuavOrgProject), a mailiing list (http://lists.paparazziuav.org/), a Gitter channel (https://gitter.im/paparazzi/discuss), a generated doc (http://docs.paparazziuav.org/) and of course the Wiki (http://wiki.paparazziuav.org/wiki/Main_Page). With this you should find the information or the help you need.


    Paparazzi UAS: Onboard Modules
  • @Marc Dornan

    I guess the following link answers your questions about the (offline) waypoint visualization/edition.


    Note that whatever block your design for your flight plan can be associated to different widgets, for example, a button. There are already some "primitives" available as buttons such as kill motor, +5m altitude, etc. It is true that it would be nice to have an offline "drag and drop" editor like in CAD Software, it would be nice to have more "UI guys", any volunteers? :P.

    Flight Plan Editor - PaparazziUAV
  • Hi Marc Dornan,

    Here's a link to the wiki page that describes the semantics and syntax of flight plans as used in Paparazzi UAV:

    Flight Plans

    Included in the page is the discussion of waypoints. Here's the link to that section:


    You can build all kinds of waypoint navigation using the GCS if you like but you are not restricted to just using waypoints. There are many nice constructs for creating rule/goal based behaviors in support of autonomy. The flight plan gives you the ability to build fairly complex state machines/models beyond just waypoint navigation.

    I think a great way to learn Paparazzi UAV is to use it. Your approach of having a specific problem to solve will give you a nice way to compare how Paparazzi can be used to solve the problem vs. some other approach: Ardupilot, etc.... That is the same approach I used when looking at the various open source UAV solutions and came to the conclusion that, for my purposes, Paparazzi UAV was the right choice.

    Also, I've really enjoyed the support and camaraderie of the Paparazzi UAV community. Folks are pretty happy to help when you find yourself in need of bouncing around an idea or resolving an issue.

    Flight Plans - PaparazziUAV
  • Gauthier,

    Nice project. I understand Paparazzi has a good multi UAV controller. One of my goals this year is to get a Lisa M autopilot I picked used into a Bixler 3 and give Paparazzi and whirl (either before or after iNav, which is also progressing nicely). I notice that you have to upload missions with blocks of code, which looks easy enough. Is there a UI tool that makes flight planning easier for Paparazzi? One wonders why a GCS with easy waypoint visualization not been developed?

    What advantages does Paparazzi offer over Ardupilot for this kind of work? I can see that its code is rather easier to delve into -- Ardupilot is pretty intimidating now.

    I only ask out of curiosity and a desire to learn more.


  • It is not in a public repository at the moment, but the flight plan itself looks like this: https://gist.github.com/gautierhattenberger/c81f3f508954d175c04abb3...

    <flight_plan alt="650" ground_alt="600" home_mode_height="60" lat0="43.1231452" lon0="0.3653030" max_dist_from_home="1000" name="Flights Campistrou" qfu="270" security_height="40">
    #include "subsystems/datalink/datalink.h"
    static inline uint8_t TEMP_DECISION(void) { if (LessThan(meteo_stick.current_temperature, 9)) return TRUE; else return FALSE; }
    static inline uint8_t TEMP_DECISION(void) { return FALSE; }
    <waypoint name="HOME" x="0" y="0"/>
    <waypoint name="CLIMB" x="164.5" y="11.1"/>
    <waypoint alt="630" name="AF" x="-120.7" y="-263.8"/>
    <waypoint alt="601" name="TD" x="-138.0" y="32.3"/>
    <waypoint name="_BASELEG" x="237.0" y="-630.9"/>
    <waypoint name="L1" x="48.7" y="-253.8"/>
    <waypoint name="L2" x="60.3" y="222.8"/>
    <waypoint name="L1H" x="28.7" y="-253.8" alt="950"/>
    <waypoint name="L2H" x="40.3" y="222.8" alt="950"/>
    <waypoint name="SP_LOW" x="-408.0" y="-4.8"/>
    <waypoint alt="1650.0" name="SP" x="-47.2" y="-201.3"/>
    <waypoint name="STNDBY" x="-37.9" y="-52.4"/>
    <waypoint lat="43.1223881" lon="0.3627727" name="TA"/>
    <waypoint lat="43.1241468" lon="0.3626271" name="TB"/>
    <waypoint alt="900.0" name="C1" x="121.2" y="-198.1"/>
    <waypoint alt="900.0" name="C2" x="-232.6" y="-186.8"/>
    <waypoint alt="601" name="BUNGEE" x="-50.5" y="50.3"/>
    <exception cond="GetPosAlt() > 2100" deroute="Standby"/>
    <exception cond="datalink_time > (8*60)" deroute="Standby"/>
    <block name="Wait GPS">
    <set value="1" var="kill_throttle"/>
    <while cond="!GpsFixValid()"/>
    <block name="Geo_init">
    <while cond="LessThan(NavBlockTime(), 10)"/>
    <!--call fun="NavSetGroundReferenceHere()"/-->
    <block name="Holding point">
    <set value="1" var="kill_throttle"/>
    <attitude roll="0" throttle="0" vmode="throttle"/>
    <block name="Bungee take-off">
    <call fun="nav_bungee_takeoff_setup(WP_BUNGEE)"/>
    <call fun="nav_bungee_takeoff_run()"/>
    <deroute block="Standby"/>
    <block group="home" name="Takeoff" strip_button="Takeoff (wp CLIMB)" strip_icon="takeoff.png">
    <exception cond="GetPosAlt() > GetAltRef()+30" deroute="Standby"/>
    <set value="0" var="kill_throttle"/>
    <set value="0" var="autopilot_flight_time"/>
    <go from="HOME" pitch="15" throttle="1.0" vmode="throttle" wp="CLIMB"/>
    <block group="home" name="Standby" strip_button="Standby" strip_icon="home.png">
    <circle radius="nav_radius" wp="STNDBY"/>
    <block group="sp" name="Spiral UP" strip_button="Spiral Profile (SP) Up" strip_icon="up_profile.png">
    <set value="2." var="fp_climb"/>
    <circle climb="fp_climb" radius="nav_radius" until="GetPosAlt() > WaypointAlt(WP_SP)" vmode="climb" wp="SP"/>
    <circle radius="nav_radius" until="NavCircleCount() > 0.5" wp="SP"/>
    <block group="sp" name="Spiral DOWN" strip_button="Spiral Profile (SP) Down" strip_icon="down_profile.png">
    <set value="-2." var="fp_climb"/>
    <circle climb="fp_climb" radius="nav_radius" until="WaypointAlt(WP_SP_LOW) > GetPosAlt()" vmode="climb" wp="SP"/>
    <deroute block="Standby"/>
    <block group="sp" name="Spiral UP Temp">
    <exception cond="TEMP_DECISION()" deroute="Spiral DOWN"/>
    <set value="2." var="fp_climb"/>
    <circle climb="fp_climb" radius="nav_radius" until="GetPosAlt() > WaypointAlt(WP_SP)" vmode="climb" wp="SP"/>
    <circle radius="nav_radius" until="NavCircleCount() > 0.5" wp="SP"/>
    <deroute block="Spiral DOWN"/>
    <block group="oval_pattern" name="Oval L1-L2" strip_button="Oval (L1-L2)">
    <oval p1="L1" p2="L2" radius="nav_radius"/>
    <block group="oval_pattern" name="Oval L1-L2 High">
    <oval p1="L1H" p2="L2H" radius="nav_radius"/>
    <block group="oval_pattern" name="Oval UP" strip_button="Oval Climb (C1-C2)">
    <set value="2." var="fp_climb"/>
    <oval climb="fp_climb" p1="C1" p2="C2" radius="nav_radius" until="GetPosAlt() > WaypointAlt(WP_SP)" vmode="climb"/>
    <deroute block="Standby"/>
    <block group="oval_pattern" name="Oval DOWN" strip_button="Oval DOWN (C1-C2)">
    <set value="-2." var="fp_climb"/>
    <oval climb="fp_climb" p1="C1" p2="C2" radius="nav_radius" until="WaypointAlt(WP_SP_LOW) > GetPosAlt()" vmode="climb"/>
    <deroute block="Standby"/>
    <block name="Oval Towers" strip_button="Oval (TA-TB)">
    <oval p1="TA" p2="TB" radius="nav_radius"/>
    <deroute block="Standby"/>
    <block group="land" name="Land Right AF-TD" strip_button="Land right (wp AF-TD)" strip_icon="land-right.png">
    <set value="DEFAULT_CIRCLE_RADIUS" var="nav_radius"/>
    <deroute block="land"/>
    <block group="land" name="Land Left AF-TD" strip_button="Land left (wp AF-TD)" strip_icon="land-left.png">
    <set value="-DEFAULT_CIRCLE_RADIUS" var="nav_radius"/>
    <deroute block="land"/>
    <block name="land">
    <call fun="nav_compute_baseleg(WP_AF, WP_TD, WP__BASELEG, nav_radius)"/>
    <circle radius="nav_radius" until="NavCircleCount() > 0.5" wp="_BASELEG"/>
    <circle radius="nav_radius" until="And(NavQdrCloseTo(DegOfRad(baseleg_out_qdr)-(nav_radius/fabs(nav_radius))*10), 10 > fabs(GetPosAlt() - WaypointAlt(WP__BASELEG)))" wp="_BASELEG"/>
    <block name="final">
    <exception cond="GetAltRef() + 8 > GetPosAlt()" deroute="flare"/>
    <go from="AF" hmode="route" vmode="glide" wp="TD"/>
    <block name="flare">
    <go exceeding_time="10" from="AF" hmode="route" throttle="0.0" vmode="throttle" wp="TD"/>
    <attitude roll="0.0" throttle="0.0" until="FALSE" vmode="throttle"/>
    view raw meteo flight plan hosted with ❤ by GitHub
  • Moderator

    Dear Gautier, you share flight plan and setting on git?

This reply was deleted.