diff --git a/doc/sphinx/source/_static/custom.css b/doc/sphinx/source/_static/custom.css
new file mode 100644
index 0000000000..8aca23e02f
--- /dev/null
+++ b/doc/sphinx/source/_static/custom.css
@@ -0,0 +1,4 @@
+/* Removes table horizontal scrollbar and fits table content to page */
+.wy-table-responsive table td {
+white-space: normal;
+}
diff --git a/doc/sphinx/source/conf.py b/doc/sphinx/source/conf.py
index 4484e03daa..5ee07a2fc1 100644
--- a/doc/sphinx/source/conf.py
+++ b/doc/sphinx/source/conf.py
@@ -167,6 +167,10 @@ html_theme = 'sphinx_rtd_theme'
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
+html_css_files = [
+ 'custom.css',
+]
+
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
diff --git a/doc/sphinx/source/developer_guide/module_architecture_overview.png b/doc/sphinx/source/developer_guide/module_architecture_overview.png
new file mode 100644
index 0000000000..3235b10fff
Binary files /dev/null and b/doc/sphinx/source/developer_guide/module_architecture_overview.png differ
diff --git a/doc/sphinx/source/developer_guide/modules.rst b/doc/sphinx/source/developer_guide/modules.rst
index bd6c5693f3..5073035352 100644
--- a/doc/sphinx/source/developer_guide/modules.rst
+++ b/doc/sphinx/source/developer_guide/modules.rst
@@ -4,6 +4,538 @@
Modules
========
-TBD
+Modules use code generation in order to allow people to use them by only editing the vehicle's XML configuration
+as opposed to changing/adding to the code of the autopilot. This makes the paparazzi build process highly configurable.
+Typically, function calls are generated for initialization and in the main loop for timers
+(``periodic`` in Paparazzi slang) and events. The event and periodic functions of the Modules get called at the end of
+``event_task_ap`` and ``periodic_task_ap respectively``.
+
+Modules are used to configure all parts of Paparazzi other than the ``firmware`` sections.
+The build configuration for each module is described using XML description language and the located in the
+``conf/modules`` subfolder. These modules implement not only the user implemented mission specific code but also the
+low level drivers and subsystems.
+
+``sw/airborne/modules`` contains the mission specific software such as image processing, video recording or relay or
+guidance commands.
+Using existing modules
+--------------------------
+To add a module to an aircraft, add a section modules in his airframe XML file :
+
+Arbitrary airframe file: conf/airframes/myplane.xml
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+All modules must be included within firmware sections. The firmware implements some vehicle specific code using
+predefined Makefiles. The most common ``firmware`` types are ``rotorcraft`` and ``fixedwing``, but more exist and are
+all located in the ``conf/firmware`` folder.
+
+A module will consist of a ``module`` node that specifies the name of the module that should be included (in this case
+``name="my_module"``).
+The children ``define`` and ``configure`` are optional and module specific. They can be used to specify the value of
+certain variables used in the module. A ``define`` will generate compilation defines for all the targets of a module
+and can be used with or without an associated value. For more information on ``define`` and ``configure`` have a look at
+the section :ref:`Airframe Defines and GCS Settings `.
+
+
+Make Your Own
+---------------
+It is very possible to make your own module and to share it with the world. To make it even easier there is a helper tool
+called ``create_mod_qt.py`` that can be found in ``sw/tools/create_module/``. To run it you will need Python 3 and a
+few Python packages that can be installed by running in your terminal:
+
+.. code-block:: bash
+
+ cd paparazzi/sw/tools/create_module
+ python3 -m pip install -r requirements.txt
+ python3 create_mod_qt.py
+
+This program can also be launched directly from the Paparazzi Center, by selecting ``Tools -> Module Creator`` from the
+Menu bar.
+Try it, you'll be surprised how easy it is to start your own module with the help of this tool.
+
+Another way to go about creating your module is by copying another module's files and editing the relevant parts.
+In order to do this, it is necessary to understand a bit more about how modules work in Paparazzi, starting with where
+all the files of a module are located.
+
+
+Module Files Location
+-----------------------
+Modules consist of the following files: a module XML file, source and header files.
+
+.. code-block:: text
+
+ ├── conf
+ │ ├── airframes
+ │ ├── autopilot
+ │ ├── flight_plans
+ │ ├── modules <---- Contains module XML with description, defines, compilation instructions
+ │ ├── radios
+ │ ...
+ ├── doc
+ ├── sw
+ │ ├── airborne
+ │ │ └── modules <---- Contains module source and header files
+ │ ├── ext
+ │ ...
+ ...
+
+
+.. _label-module-xml:
+
+Module XML
+--------------
+The module description files are located in ``conf/modules/``. They contain information such as a description of the module,
+module settings that can be controlled from the GCS, which source files are needed to compile the module, and additional
+module specific compiler flags.
+
+.. image:: module_architecture_overview.png
+
+Here is an example of a module XML file. Not all of the XML nodes that are shown are actually required, as will be explained
+in this section.
+
+.. code-block:: xml
+
+
+
+
+
+
+ Demo module
+
+
+
+
+
+
+
+
+
+
+
+
+ module1,module2|module3,@functionality1
+ functionality2
+ module4,@functionality3
+
+
+
+
+
+
+
+
+
+
+
+ #Example of RAW makefile part
+
+
+
+
+
+
+
+
+
+
+
+
+
+The XML file starts with a ``module`` element that sets the name of the module (in this case ``demo_module``).
+Optionally, this element can contain a ``dir`` attribute as well, to specify the location of the source files relative to
+``sw/airborne/modules/``.
+In this case the directory is not provided since the source files are located in a directory inside ``sw/airborne/modules/``
+that has the same name as the module name (``sw/airborne/modules/demo_module/``).
+
+After a documentation and dependency section, the XML contains a `header` element, where the header files of the
+module are listed.
+Typically, you will only see one header file here that provides an easy-to-use access point for other modules.
+
+The header element is often followed by an ``init`` and ``periodic`` element.
+These specify what functions in your module code should be called by the autopilot, and in case of the periodic function
+it also specifies its frequency in Hz. The other two function types that can be specified consist of ``event`` and
+``datalink`` functions.
+
+At the end of the XML file is the `makefile` element. This section describes how your source files should be compiled.
+Simple modules such as the demo_module only list one or more source files. More complicated modules such as
+``cv_opencvdemo`` can specify additional compiler flags (to link OpenCV, for example) and can have different
+makefile sections depending on whether the autopilot is compiled for use on the drone (``target="ap"``) or in
+simulation (``target="nps"``).
+
+The source and header files of your module can be found in ``sw/airborne/modules//``.
+We take a closer look at the content of these files in the :ref:`Header ` and
+:ref:`Source ` Sections.
+
+Here is an overview of all possible Module XML nodes:
+
+
++---------------+---------------+-------------------------------------------------------------------------+
+| Node | Children | Description |
++===============+===============+=========================================================================+
+| | name | This parameter is the name of the module (mandatory) |
+| | (required) | |
+| | module +---------------+-------------------------------------------------------------------------+
+| | (required) | | The name of the directory in ``sw/airborne/modules`` where the source |
+| | dir | code is located. If not specified, the name of the module is used as |
+| | | default directory name |
++---------------+---------------+-------------------------------------------------------------------------+
+| | description | A description of the module. The content of the first line until |
+| | (required) | the dot is treated as the brief description used as the name in |
+| | | the generated docs |
+| +---------------+-------------------------------------------------------------------------+
+| | define | Describe the possible define flags for this module with default |
+| | | values and a short description (usually called from the airframe |
+| | doc | | firmware section |
+| | (optional) +---------------+-------------------------------------------------------------------------+
+| | configure | Describe the possible configuration options for this module with |
+| | | default values and a short description (usually called from the |
+| | | airframe firmware section |
+| +---------------+-------------------------------------------------------------------------+
+| | section | Describe the parameters that can be added as a section in the |
+| | | airframe configuration file |
++---------------+---------------+-------------------------------------------------------------------------+
+| | target | A list of targets allowed or forbidden for which embedded settings |
+| | | should be used |
+| | settings +---------------+-------------------------------------------------------------------------+
+| | (0 or more) | dl_settings | Creates a tab with arbitrary name that can be specified with |
+| | | ``name="your-tab-name"`` |
+| +---------------+-------------------------------------------------------------------------+
+| | dl_setting | Setting description, see :ref:`Settings ` |
+| | (child of | section for details |
+| | dl_settings) | |
+| | | |
+| | | |
++---------------+---------------+-------------------------------------------------------------------------+
+| | | Comma separated list of required modules |
+| | dep | | |
+| | (0 or 1) | depends | |
+| | | Allows to specify OR dependencies with pipe |
+| | | (\|) similar to Debian depends, ex: ``module1,module2|module3`` |
+| | | would make it depend on ``module1 AND (module2 OR module3)`` |
+| | | |
+| | | The elements can be a module name (as set in the module XML ``name`` |
+| | | node) or a functionality (a keyword specified in a ``provides`` node), |
+| | | which has to be preceded by @ |
+| +---------------+-------------------------------------------------------------------------+
+| | provides | Advertises the functionality that the module provides (e.g. actuators, |
+| | | imu) |
+| +---------------+-------------------------------------------------------------------------+
+| | conflicts | Comma separated list of conflicting modules |
+| | | |
+| | | The elements can be a module name (as set in the module XML ``name`` |
+| | | node) or a functionality (a keyword specified in a ``provides`` node), |
+| | | which has to be preceded by @ |
++---------------+---------------+-------------------------------------------------------------------------+
+| | autoload | name | The name of the module which should also be automatically loaded |
+| | (0 or 1) | | |
++---------------+---------------+-------------------------------------------------------------------------+
+| | header | file | The name of the header to automatically include in modules.h |
+| | (0 or 1) | | |
++---------------+---------------+-------------------------------------------------------------------------+
+| | init | fun | Initialization function name, called once at startup |
+| | (0 or more) | | |
++---------------+---------------+-------------------------------------------------------------------------+
+| | periodic | fun | Periodic function name |
+| | (0 or more) | (required) | |
+| +---------------+-------------------------------------------------------------------------+
+| | period | Period of the function in seconds, cannot be higher than the main |
+| | | frequency (if not specified, use freq parameter) |
+| +---------------+-------------------------------------------------------------------------+
+| | freq | Frequency of the function in Hz, cannot be higher than main frequency |
+| | | (used if period is not defined; if nor period nor freq are defined, |
+| | | the maximum frequency is used by default) |
+| +---------------+-------------------------------------------------------------------------+
+| | delay | Integer that can be used to impose a sequence in the periodic functions |
+| | | (use values between 0. and 1.) |
+| +---------------+-------------------------------------------------------------------------+
+| | start | Function to be executed before the periodic function starts |
+| +---------------+-------------------------------------------------------------------------+
+| | stop | Function to be executed after the periodic function stops (never called |
+| | | if ``autorun=LOCK``) |
+| +---------------+-------------------------------------------------------------------------+
+| | autorun | TRUE to make the periodic function starts automatically after init, |
+| | | FALSE to make it way for a user command to start, LOCK to make it |
+| | | always true (default is LOCK) |
++---------------+---------------+-------------------------------------------------------------------------+
+| | event | fun | Event function name called in each cycle of the main AP loop |
+| | (0 or more) | | |
++---------------+---------------+-------------------------------------------------------------------------+
+| | datalink | message | Name of the datalink (uplink) message to be parsed |
+| | (0 or more) +---------------+-------------------------------------------------------------------------+
+| | fun | Name of the function called when a message arrived |
++---------------+---------------+-------------------------------------------------------------------------+
+| | makefile | target | A list of build targets separated with pipes |
+| | (0 or more) | | (ex: ````) |
+| | | (default is ``ap|sim|nps``) |
+| +---------------+-------------------------------------------------------------------------+
+| | define | Each define node specifies a CFLAGS for the current targets |
+| | | |
+| | | - | `name` : name of the define (ex: ``name="USE_MODULE_LED"`` -> |
+| | | | ``target.CFLAGS += -DUSE_MODULE_LED``) (required) |
+| | | |
+| | | - | `value` : the value to associate |
+| | | | (ex: ``name="DEMO_MODULE_LED" value="2"`` -> |
+| | | | ``target.CFLAGS += -DDEMO_MODULE_LED=2``) |
+| | | |
+| | | - | `type` : the type of define, possible values are "define" or "D", |
+| | | | "include" or "I" (ex: ``name="$(ARCH_SRC)" type="include"`` -> |
+| | | | ``target.CFLAGS += -I$(ARCH_SRC)`` default is "define" |
+| +---------------+-------------------------------------------------------------------------+
+| | file | - | `name` : the name of the c file (located in |
+| | | | ``sw/airborne/modules/``) to add in the Makefile |
+| | | | (ex: ``name="demo_module.c"`` -> |
+| | | | ``target.srcs += modules//demo_module.c)`` |
+| | | |
+| | | - | `dir` : select a directory for this file only |
+| | | | (overrides thedefault directory) |
+| | | |
+| | | - | `cond` : allows for the conditional compilation of file depending |
+| | | | on the condition specified (ex. ``cond="ifdef FOO"`` -> |
+| | | | ``ifdef FOO`` |
+| | | | ``...`` |
+| | | | ``endif`` |
+| | | | As the ``file`` node refers to compilation elements, ``ifdef``, |
+| | | | ``ifeq`` etc. must be specified in value of the ``cond`` attribute |
+| +---------------+-------------------------------------------------------------------------+
+| | file_arch | - | `name` : the name of the c file (located in |
+| | | | ``sw/airborne/arch//modules/``) add in the Makefile |
+| | | | (ex: ``name="demo_module_hw.c"`` -> |
+| | | | ``target.srcs += arch//modules//demo_module_hw.c``) |
+| | | |
+| | | - | `dir` : select a directory for this file only |
+| | | | (overrides the default directory) |
+| | | |
+| | | - | `cond` : allows for the conditional compilation of file depending |
+| | | | on the condition specified (ex. ``cond="ifdef FOO"`` -> |
+| | | | ``ifdef FOO`` |
+| | | | ``...`` |
+| | | | ``endif`` |
+| | | | As the ``file`` node refers to compilation elements, ``ifdef``, |
+| | | | ``ifeq`` etc. must be specified in value of the ``cond`` attribute |
+| +---------------+-------------------------------------------------------------------------+
+| | raw | Allows to define a raw makefile section |
++---------------+---------------+-------------------------------------------------------------------------+
+
+
+Starting and Stopping a module
+---------------------------------
+
+Together with the periodic function, the module XML can specify a ``START`` and ``STOP`` function. These are called when
+the module is started or stopped, respectively. The ``autorun`` attribute in the module XML's ``periodic`` element
+controls whether your module is started automatically or manually; you can manually start and stop modules from the GCS
+by going to ``Settings -> System -> Modules``, selecting ``START`` or ``STOP`` and clicking the green checkmark.
+You can find an example of start and stop functions functions in ``sw/airborne/modules/loggers/file_logger.c``,
+where they are used to open and close the log file.
+
+If modules are loaded with periodical functions that are not locked, a new tab will automatically appear in the setting
+page of the GCS that allows you to start and stop them.
+
+An other possibility is that any file that includes the header "modules.h" can start or stop the periodic tasks.
+
+
+.. _label-module-header-file:
+
+Module Header File
+---------------------
+
+The module header is located in ``sw/airborne/modules//``, and functions like a normal .h
+file. The main difference is that any function or variable that is referenced by an XML file needs to be defined as
+``extern`` so that the compiler can find the definition.
+
+By convention any variable and function that is defined in a module header, especially if used outside of the module by
+another module or XML, should be prefixed with the module name or some other unique identifier to help avoid name
+collision.
+
+
+.. _label-module-source-file:
+
+Module Source File
+--------------------
+
+The autopilot will regularly call functions that are part of your module, such as a module periodic
+function. Which functions are called is defined by the module XML file described earlier.
+
+The section `Module XML`_ lists the types of functions you can register in the module XML: ``init``, ``periodic``,
+``event`` and ``datalink``, of which init and periodic are the most common.
+The ``init`` function is called once at startup. You can use this function to initialize important variables of your
+module, or memory intensive structures such as large arrays, or for instance to subscribe to new video frames.
+Once the autopilot is fully initialized, it will enter an infinite loop in which it will continuously read new sensor
+data, feed this to the guidance and stabilization controllers, and send new commands to the actuators.
+From this loop, the autopilot can also call your module's ``periodic`` function at a frequency specified in the
+module XML.
+Within this function, you can for instance get the drone's state and use this to calculate new setpoints for the
+guidance controller.
+
+Because the periodic function is called from within the autopilot's control loop, you should take care that the
+function does not take too much time to run. The autopilot runs by default at 512~Hz, which means that it has slightly
+less than 2~ms to run your module code, the code of the other modules and the control loops and estimators.
+If your periodic function takes too long, the autopilot will run at a lower frequency than intended, which can lead to
+instability.
+In practice you have to make things pretty bad before this becomes a problem, but you should be careful when using
+large or nested loops in your periodic function, and video processing is best performed in the video callback function,
+as this callback runs in a separate thread.
+
+.. warning::
+ If your periodic function takes too long, the autopilot will run at a lower frequency than intended, which can
+ lead to instability
+
+
+.. _label-defines-and-settings:
+
+Airframe Defines and GCS Settings
+------------------------------------
+
+A module will most likely contain tunable parameters, such as gain or threshold values. While these numbers can be
+written directly in the source code, this will make it difficult to tune them later, as every time that they are
+changed you will need to rebuild and reupload to your drone. Paparazzi provides two systems to simplify parameter
+tuning: defines and settings.
+
+Defines allow you to set constant values from the airframe file. See, for example, the following abstract of the
+``bebop_course_orangeavoid.xml`` airframe:
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+As you can see, defines can be set at multiple places in the airframe file. The behavior is mostly the same in these
+cases, with the following exceptions:
+
+- Defines placed in the ```` elements are only set when the autopilot is built for that target,
+ i.e. ``"ap"`` for the real drone and ``"nps"`` for the simulator. This allows you to, for instance, use
+ different color filter settings on the real and simulated drone.
+
+- Placing a define inside a ```` element has no special effect! The define is also visible in other modules,
+ so be sure to use a unique name. Typically, defines are prefixed with the name of the module (e.g.
+ ``COLOR_OBJECT_DETECTOR_`` to make them unique. The only reason these defines are placed inside the module
+ element is to improve readability.
+
+- ```` elements allow you to specify a ``prefix``, this prefix is placed in front of all
+ define names inside this section. In the example, the ``CLIMB_VSPEED`` define is available in the code as
+ ``GUIDANCE_H_CLIMB_VSPEED``.
+
+During compilation, these defines are turned into preprocessor macros and can be referred to directly from your code.
+
+Airframe defines allow you to set constant parameters at compile-time, but in some cases it would be easier if you
+could change these values during the flight. This is possible with the
+`settings `_ mechanism. Settings are defined in the module XML file.
+Take for example ``conf/modules/cv_detect_color_orange.xml``:
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+`Settings `_ listed in the module XML can be tuned from the
+Ground Control Station by going to the `Settings` tab and then selecting the tab belonging
+to your module, as defined in the ``dl_settings`` element (here ``ColorObjectDetector``). To read the current value of
+a parameter from the drone, click its value (the number) in the GCS. Te set a value on the drone, adjust the slider,
+*then click the green checkmark* to upload this new value to the drone . Click the value number again to make sure the
+setting was updated if a question mark appears to the left of the slider. The updated value should appear to the left
+of the slider.
+
+Use the ``dl_setting`` element in your module XML to add a setting to your module. The ``var`` attribute
+specifies the variable this setting should be written to; this variable should be globally accessible (defined as
+``extern`` in the h file).
+The ``min``, ``step`` and ``max`` attributes let you specify a range of possible values for this setting.
+Using ``shortname`` you can control the name under which this setting is listed in the GCS.
+The ``module`` attribute can be added to specify the file where the variable is coming from.
+A corresponding #include "m.h" will be auto-generated in the corresponding C code.
+
+In case of more complicated logic that needs to be triggered any time that a GCS variable is changed (like resetting
+certain variables, or changing the value of more variables at once) a ``handler`` attribute can be added to specify
+a function (or a macro) to be called whenever the setting is changed. This macro is associated with a module and
+**must be named** ``_()``.
+
+As an example, take a look at an excerpt from ``conf/modules/digital_cam.xml``:
+
+.. code-block:: xml
+
+
+
+
+
+The ``module`` attribute is specified as ``module="digital_cam/dc"``. While in the XML the handler
+function is specified as ``send_command``, in the source code the module name must be added in front of the function
+name, as can be seen in ``sw/airborne/modules/digital_cam/dc.h``.
+
+.. code-block:: C
+
+ extern void dc_send_command(uint8_t cmd);
+
+It is possible to combine the define and settings mechanisms, where the define provides a default value that can be
+adjusted later using settings. This often uses the following pattern:
+
+.. code-block:: C
+
+ #ifndef MY_DEFINE
+ #define MY_DEFINE 0
+ #endif
+ int my_setting = MY_DEFINE;
+
+In this example, ``MY_DEFINE`` provides the initial value of ``my_setting``. ``MY_DEFINE`` can be set from
+the airframe file, but if it is not defined there this code will give it a default value of 0. The actual parameter
+is stored in ``my_setting``, for which a ```` element is included in the module's XML file.
+
+
+Third Party Modules
+---------------------
+It is possible to include third party modules in an airframe, or modules that are not located within the Paparazzi
+folder itself. The extra directories can be added with the environment variable ``PAPARAZZI_MODULES_PATH``, where
+items are ``:`` separated and modules are in subfolders of a `modules` folder.
+Ex. ``PAPARAZZI_MODULES_PATH=/home/me/pprz_modules``. This directory should look like this:
+
+.. code-block:: text
+
+ ├── pprz_modules
+ │ ├── modules
+ │ │ ├── module1
+ │ │ │ ├── module1.xml
+ │ │ │ ├── module1.h
+ │ │ │ └── module1.c
+ │ │ ├── module2
+ │ │ │ ├── module2.xml
+ │ │ │ ├── module2.h
+ │ │ │ └── module2.c
+ | │ ...
+ | ...
+ ...
diff --git a/doc/sphinx/source/index.rst b/doc/sphinx/source/index.rst
index 85e595c89c..68f0060c5e 100644
--- a/doc/sphinx/source/index.rst
+++ b/doc/sphinx/source/index.rst
@@ -28,8 +28,8 @@ Contents:
:maxdepth: 2
quickstart/index_quick_start
- user_guide/index_user_guide
installation/index_installation
+ user_guide/index_user_guide
developer_guide/index_developer
tutorials/index_tutorials
support/index_support