diff --git a/History.txt b/History.txt
deleted file mode 100644
index 743a948..0000000
--- a/History.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-=== / 2014-05-19
- * adapt creation to allow for gem creation
diff --git a/Manifest.txt b/Manifest.txt
deleted file mode 100644
index d0f42f5..0000000
--- a/Manifest.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-README.markdown
-manifest.xml
-Rakefile
-Manifest.txt
-scripts/aggregator/plots.rb
-scripts/aggregator/plot_timestamper_stats.rb
-test/suite_orogen.rb
-test/orogen/test_trajectory_follower.rb
-test/orogen/test_canbus.rb
-test/orogen/test_taskmon.rb
-test/orogen/test_envire.rb
-test/orogen/test_gps.rb
-models/orogen/camera_firewire.rb
-models/orogen/laser_filter.rb
-models/orogen/parport.rb
-models/orogen/icp.rb
-models/orogen/stereo.rb
-models/orogen/corridor_navigation.rb
-models/orogen/laserscanner_sick.rb
-models/orogen/skid4_control.rb
-models/orogen/trajectory_follower.rb
-models/orogen/hokuyo.rb
-models/orogen/camera_prosilica.rb
-models/orogen/fog_kvh.rb
-models/orogen/camera_usb.rb
-models/orogen/camera_unicap.rb
-models/orogen/gps.rb
-models/orogen/joint_dispatcher.rb
-models/orogen/pose_estimator.rb
-models/orogen/corridor_planner.rb
-models/orogen/iodrivers_base.rb
-models/orogen/envire.rb
-models/orogen/vicon.rb
-models/orogen/simulation.rb
-models/orogen/sonar_tritech.rb
-models/orogen/transformer.rb
-models/orogen/servo_dynamixel.rb
-models/orogen/dynamixel.rb
-models/orogen/controldev.rb
-models/orogen/xsens_imu.rb
-models/orogen/taskmon.rb
-models/orogen/canbus.rb
-models/orogen/stim300.rb
-models/blueprints/planning.rb
-models/blueprints/control.rb
-models/blueprints/map_gen/map_generator_srv.rb
-models/blueprints/map_gen/pipeline_base.rb
-models/blueprints/sensors.rb
-models/blueprints/vision.rb
-models/blueprints/pose.rb
-models/blueprints/map_gen.rb
-models/blueprints/devices.rb
-models/blueprints/timestamping.rb
-config/init.rb
-config/app.yml
-History.txt
diff --git a/README.markdown b/README.markdown
deleted file mode 100644
index eb0fe33..0000000
--- a/README.markdown
+++ /dev/null
@@ -1,26 +0,0 @@
-# Bundle: rock
-
-* http://www.rock-robotics.org
-
-# DESCRIPTION
-
-Bundles are packages that offer a "system-wide" view of software functionality
-in Rock.
-
-* http://rock.opendfki.de/wiki/WikiStart/Standards/RG7 for a detailed description
-
-This bundle provides syskit models and scripts to use Rock's navigation algorithms / components.
-If you decide to use rock-roby, Rock's system management layer a set of standard folders exists.
-
-Details can be found here:
-
-* http://rock-robotics.org/master/documentation/system/index.html
-
-For example:
-
-* models/ holds the model definition files for Roby-based applications
-* scripts/controllers/ contains the Roby controller files.
-
-# LICENSE
-
-* LGPLv2 or later
diff --git a/Rakefile b/Rakefile
index 1cc8c78..1a30ce7 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,36 +1,20 @@
-task :default
-
-package_name = 'rock'
-begin
- require 'hoe'
+# frozen_string_literal: true
- Hoe::plugin :yard
+require "yard"
+require "yard/rake/yardoc_task"
+require "roby/app/rake"
- hoe_spec = Hoe.spec package_name do
- self.version = '0.1'
- self.developer "Sylvain Joyeux", "sylvain.joyeux@mx4.org"
- self.extra_deps <<
- ['rake', '>= 0.8.0'] <<
- ["hoe", ">= 3.0.0"] <<
- ["hoe-yard", ">= 0.1.2"]
+task :default
- self.summary = 'Root bundle for Rock software'
- self.readme_file = FileList['README*'].first
- self.description = paragraphs_of(readme_file, 3..5).join("\n\n")
- self.licenses << "LGPLv2 or later"
- self.yard_opts = [ 'models/', 'scripts/', 'config/', 'test/' ]
+Roby.app.load_base_config
- self.spec_extras = {
- :required_ruby_version => '>= 1.8.7'
- }
- end
+Roby::App::Rake::TestTask.new("test")
- # If you need to deviate from the defaults, check utilrb's Rakefile as an example
+YARD::Rake::YardocTask.new do |yard|
+ yard.files = ["yard/externals.rb", "models/**/*.rb", "lib/**/*.rb"]
+end
- Rake.clear_tasks(/^default$/)
- task :default => []
- task :doc => :yard
+desc "Generate YARD documentation (alias for 'yard')"
+task "doc" => "yard"
+task :default
-rescue LoadError => e
- puts "Extension for '#{package_name}' cannot be build -- loading gem failed: #{e}"
-end
diff --git a/manifest.xml b/manifest.xml
index 8033cb4..92ac0a1 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -8,5 +8,6 @@
LGPL v2 or later
+
diff --git a/yard/externals.rb b/yard/externals.rb
new file mode 100644
index 0000000..7124237
--- /dev/null
+++ b/yard/externals.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Syskit
+ # Placeholder to tell YARD this class exists
+ class Component; end
+end
+
+module Roby
+ module Queries
+ # Placeholder to tell YARD this class exists
+ class TaskMatcher; end
+ end
+end
diff --git a/yard/missions.md b/yard/missions.md
new file mode 100644
index 0000000..4ef35d4
--- /dev/null
+++ b/yard/missions.md
@@ -0,0 +1,201 @@
+# Missions
+
+The missions are the high-level (read: UI-oriented) interface to the system. There
+can be only one mission active at any given time.
+
+The REST API that allows to manipulate them is currently defined in `bundles/wetpaint`,
+in `Wetpaint::REST::MissionAPI` and `Wetpaint::REST::MissionHelpers`. This package
+defines the lower level elements on top of which the missions are built.
+
+The core of the mission system is to offer a JSON representation for missions, and
+a mean to both represent them before they are executed, and to instanciate them
+through the action system.
+
+The available endpoints are described in the list below. They are defined relatively
+to where `Wetpaint::REST::MissionAPI` is mounted, which is
+`signalk/v1/api/resources/mission` in the Wetpaint system. Each endpoint is
+detailed in separate sections.
+
+| Endpoint | Description |
+| -------- | ------------------------------------ |
+| POST / | [Create a new mission](#creating-a-new-mission) |
+| GET /:mission_id | [Query information about a created mission](#inspecting-an-existing-mission) |
+| PUT /:mission_id/state | [Change a mission's state](#changing-a-mission-state) |
+
+## Workflow
+
+Missions must first be [created](#create). Once created, they can be
+[queried](#get) or their [state modified](#changing-a-mission-state). Missions are
+one-use-only, i.e. once running and/or finished they cannot be restarted (but an
+identical mission can easily be created by querying the mission parameters and
+creating a new one)
+
+## Error Handling
+
+On error, the endpoints will return an appropriate HTML error code (documented for each
+endpoint) as well as a JSON object with appropriate information.
+
+## Creating a new mission
+
+### Endpoint
+
+`POST /`
+
+### Arguments
+
+| Argument | Type | Description |
+| -------- | ---- | ----------- |
+| type | string | The type of the mission being created |
+| * | | Other arguments are specific to the mission type, see [existing mission types](#mission-types) |
+
+### Return Value
+
+| Field | Type | Description |
+| ----- | ---- | ----------- |
+| missionId | string | The mission ID |
+
+### Errors
+
+| Description | Code | Error Object |
+| ----------- | ---- | ------------ |
+| type is not an existing mission type | 400 | { "error": { "message": "invalid mission type 'TYPE'" }}
+| the fields do not match the required/optional fields from the mission type | 400 | { "error": { "message": "description of the error" }}
+
+### Example
+
+`POST /` with arguments `{ "type": "transit", "routeId": "some-id" }` returns `{ missionId: "the-mission-id" }`
+
+### Detailed Description
+
+A mission has first to be created with a POST to the root of the MissionAPI
+(mounted under in the Wetpaint system). The only required argument is the
+`type` argument, which defines how the rest of the arguments will be
+interpreted. The endpoint returns the new mission's ID, which is an arbitrary
+string that allows to refer to the mission in the rest of the API
+
+The API calls `Seabots::Missions.from_json` that resolves the mission class
+using the `type` argument. The type-to-class mapping is done using the
+`Seabots::Missions::MISSION_TYPE_TO_CLASS` hash. `Missions.to_json` then
+delegates to the `#to_json` method of the instance of the new class.
+
+After creation, the mission instance is store internally but not yet added
+to the system's running plan
+
+## Inspecting an existing mission {#get}
+
+### Endpoint
+
+`GET /:mission_id`
+
+### Arguments
+
+| Name | Type | Description |
+| -------- | ---- | ----------- |
+| mission_id | string | The ID of the mission, as returned on creation |
+
+### Return Value
+
+| Field | Type | Description |
+| -------- | ---- | ----------- |
+| missionId | string | The ID of the mission, as returned on creation |
+| state | string | The mission state (see [the list of mission states](#mission-states)) |
+| * | | The mission parameters, identical to the ones given to {#create}. They are type-specific, see [the existing mission types](#mission-types) for more information |
+
+### Detailed description
+
+The endpoint returns a JSON document of the same format than the one used for
+creation, augmented with mission ID and state information.
+
+## Changing a mission state
+
+### Endpoint
+
+`PUT /:mission_id/state`
+
+### Arguments
+
+| Name | Type | Description |
+| -------- | ---- | ----------- |
+| mission_id | string | The ID of the mission, as returned on creation |
+| value.target | string | `running` or `terminated` |
+
+### Return Value
+
+This endpoint does not return anything
+
+### Errors
+
+| Description | Code | Error Object |
+| ----------- | ---- | ------------ |
+| value.target is `running` but the mission has already finished | 400 | { "error": { "message": "mission has been started but finished or was aborted" }}
+| value.target is `stopped` but the mission is neither active nor running | 400 | { "error": { "message": "mission has been started but finished or was aborted" }}
+| value.target is invalid | 400 | { "error": { "message": "invalid target state" }}
+
+### Detailed Description
+
+This endpoint allows to change the [mission's state](#mission-states). A created
+mission that has never been started can be started by calling it with the
+`running` target. An active or running mission can be terminated with
+`terminated`
+
+The endpoint is idempotent. One can call with a `running` target while in
+`active` or `running` state, or `terminated` on a finished mission.
+
+Making a mission active will automatically terminate any other active mission.
+
+## Existing Mission Types
+
+### Transit
+
+The transit mission represents a route following behavior. The route has to be
+created and the trajectory planned separately using the relevant APIs.
+
+The transit mission requires the following parameters:
+
+| Field | Description |
+| ----- | ----------- |
+| routeId | The ID of a planned route |
+### Survey
+
+The survey mission represents following a route for the purpose of survey. The
+route has to be created and the trajectory planned separately using the relevant
+APIs.
+
+| Field | Description |
+| ----- | ----------- |
+| routeId | The ID of a planned route |
+
+## Mission States
+
+| Name | Description |
+| ---- | ----------- |
+| pending | Created but never started |
+| active | Present in plan, but not yet running |
+| running | Running |
+| success | Finished successfully |
+| failed | Finished unsuccessfully |
+| aborted | Terminated while in `active` state (i.e. before it got even started) |
+| unknown | Invalid state (should never happen) |
+
+## Creating new mission types
+
+To create a new mission type, one has to create:
+
+- a mission class (see below)
+- a JSON schema for the mission representation in JSON
+- an action that returns an instance of this type's mission
+- register the mission class on `Seabots::Missions::MISSION_TYPE_TO_CLASS`
+
+Mission classes are subclasses of Seabots::Tasks::Missions::Base. The subclass
+**must** overload the following methods, which are documented on
+Seabots::Tasks::Missions::Base:
+
+| Name | Description |
+| ------------------ | ----------- |
+| self.from_json | Create a new mission. Should ultimately call `create(action_interface, **action_arguments)`, where `action_arguments` will be passed to `instanciate` once the mission is activated. The JSON object MUST be validated using `JSON::Schema.validate!` from [json-schema](https://github.com/voxpupuli/json-schema). The REST API catches the validation error and returns an appropriate error code (400). Additional validation errors should raise `InvalidMissionJSON` |
+| self.instanciate | Create a runnable representation of the mission. This is usually done by calling a separately defined action on `action_interface`, as e.g. `action_interface.mission_usv_transit.as_plan(**action_arguments) |
+| json_type | Return the type of the mission as string (e.g. "transit") |
+
+Additionally, the `activate` instance method can be overloaded to modify action
+arguments that need to be modified on activation. `USVTransit` for instance
+sets the trajectory's reference time to `Time.now`