MIRA
Domain Pilot - Documentation


Pilot

The Pilot domain provides main components of a modular navigator for mobile robots. The Pilot consists of a core library that contains all main classes and interfaces that are used by the separate modules.

The actual functionality of the navigator is located in different plugins. Each plugin is compiled into a separate library. The plugin concept allows to combine different algorithms to create a navigation solution that is customized for the specific application.

Most important plugins are Motion Planners, like the Dynamic Window Approach (DWA). Many motion planners that compute a cost function within the velocity space (e.g. DWA) can be modularized themselves. Those modules are called "objectives". The purpose of objectives is to evaluate motion trajectory candidates generated by the motion planner according to the current robot state. Each objective votes for a certain trajectory by computing a cost value. The cost values of all active objectives are accumulated and finally, the trajectory that yields the smallest summed cost is chosen to determine the next motion command.

In the following the channels and services are described that are required by the Pilot core unit. The used motion planner, path planner and each used objective may require additional channels and services. These are listed below.

Channels

Subscribed

Published

Services

Required

Published

Parameters

The task based system

Based on the modular concept of objectives, the navigator offers a suitable interface that allows to specify complex tasks. In order to develop a highly generic navigator, we use a task based system which allows to define jobs consisting of several sub-tasks and their corresponding parameters. To meet the requirements of different applications, many sub-tasks are defined that can be combined to create complex tasks, the most important are:

Each sub-task can be parameterized by numerous task specific options, including:

To fulfill the job, the navigator must complete each sub-task by following the specified rules and options. Moreover, the task based system allows for the addition of new sub-tasks in the future, when required, without changing the interface of existing tasks or interfering with existing applications. This is an important advantage of this task based design since it reduces the effort necessary for software maintenance.

An overview of basic task definitions can be found in the documentation of toolbox Navigation (SubTasks).

Objectives are automatically activated or deactivated upon a new task based on the contained subtasks they "understand" when using a planner derived from the AbstractObjectiveBasedPlanner.

mira::pilot::AbstractObjectiveBasedPlanner

This is the base class for all objective based planners. It provides an interface for managing objectives and defines some basic parameters. It automatically distributes a task to all active objectives, collects their votes and assigns planning times. It needs a robot model that is at least a subclass of mira::robot::UnicycleBasedRobotModel.

Services

Published

Parameters

mira::pilot::AbstractDynamicWindow

One of the most often used algorithms for anticipatory motion planning is the Dynamic Window Approach. This algorithm searches for the optimal motion command directly in the space of velocities. Therefore, the robot’s two dimensional velocity space is discretized into regular two dimensional cells where each cell represents a certain trajectory. Each cell is assigned a cost function. Finally, the velocities corresponding to the cell that yields the smallest costs are chosen as motion commands. In these computations the Dynamic Window Approach takes the robot’s dynamic into account by reducing the search space to those velocities which are reachable under the dynamic constraints such as limited speed and acceleration. Additionally, only velocities are considered that are safe and do not lead to collisions. As stated before, each cell covers a certain area of the velocity space and corresponds to a certain velocity command. For motion planning, a cost function is computed for each cell and therefore the velocity command that yields the smallest cost is chosen. For each cell of the adaptive dynamic window within the dynamic constraints of the robot, each objective is called to compute its cost value ci for that cell or to mark the associated action as “not admissible”. In the latter case the computation for the cell is aborted immediately to save computation time. The final overall cost of each cell is then computed by the weighted sum of the returned cost values ci of all objectives.

The base class of all dynamic window based algorithms (mira::pilot::AbstractDynamicWindow) implements a mira::pilot::AbstractObjectiveBasedPlanner and already provides most of the functionality and data structures needed for a dynamic window approach.

Channels

Published

mira::pilot::DynamicWindow

This class implements a mira::pilot::AbstractDynamicWindow and builds up a cell structure that uses two different sizes and resolutions for rotational dimension (DWA y-Axis) and translational dimension (DWA x-Axis).

Parameters

Distance objective

This objective is activated by default. It forbids trajectories that would lead to a collision of the robot with obstacles. It can be disabled by setting the subtask mira::navigation::IgnoreObstaclesTask. It optionally limits the robots translation to a given maximum safety speed when a safety zone is defined around the robot and a trajectory would lead to a collision of this zone with an obstacle.

The robot's rigid model is used to determine the footprint of the robot. This footprint will be checked against collisions in an occupancy grid map (typically a local map with high update rate, e.g. created from laser readings). Collision representations with name "SafetyZone" in the robot's rigid model are used to get the optional safety zone footprint of the robot.

<link name="RobotFrame">
<collision>
<include file="MyRobots-footprint.xml" />
</collision>
<collision name="SafetyZone">
<geometry>
<cylinder length="0.001" radius="0.75" />
</geometry>
</collision>
</link>

In the above example the geometry defined in the file "MyRobots-footprint.xml" is used for normal collision detection whereas the cylinder defined in the collision representation with name "SafetyZone" will be used as a safety zone around the robot for limiting the robot's speed when an obstacle violates this zone.

In addition to just avoiding collisions, the Distance objective can be used to actually keep a defined minimum distance to obstacles, using a KeepDistanceTask. In contrast to collision avoidance, the distance is not calculated with respect to the exact robot shape, but assumes a circular shape (with a configurable radius, by default the robot's outer radius). The minDistance parameter from the KeepDistanceTask will be used to deny trajectories getting closer to obstacles than this limit, while undershooting the criticalDistance will be interpreted as another moving object actively approaching the robot and result in signalling dissatisfaction (Reason: Interference). In praxis, both thresholds are dynamically adapted continuously, regarding the obstacle distance at the current position and the obstacle distance at the (planned) target position (if in reach). This will account for measurement noise and allow reaching (and leaving) targets although they are closer to the next obstacle than the KeepDistanceTask would permit.

The desiredDistance parameter in KeepDistanceTask can be set to a value higher than minDistance to assign an additional cost if a trajectory's obstacle distance is between minDistance and desiredDistance. This needs good balancing with other costs e.g. from PathObjective though and is discouraged for all but the most experienced (or experimentally inclined) users.

Channels

Subscribed

Published

Parameters

Path objective

This objective is activated by the subtask mira::navigation::PositionTask. It plans a path on the global map and votes for following the path to the goal area.

Channels

Subscribed

Published

Transforms

Parameters

Heading objective

This objective is activated by the subtask mira::navigation::OrientationTask. It will rotate the robot to face into the given direction. When combined with the Path objective the robot will first drive to the given goal and then rotate to face the given direction.

The HeadingObjective provides two methods of recovery. The first one is RecoveryMode::SetDissatisfaction, which corresponds to the standard Pilot recovery mechanisms. The second one is RecoveryMode::TurnAway. In this mode the robot turns away from the goal orientation and tries to reach it from the other side.

Transforms

Parameters

Direction objective

This objective is activated by the mira::navigation::PreferredDirectionTask. It implements the preferred or prohibited driving directions of a robot.

Channels

Subscribed

Parameters

Mileage objective

This objective is activated by the subtask mira::navigation::MileageTask. The task is reached if the robot has driven a given mileage since the task was activated. It can be used together with the Explore objective.

Channels

Subscribed

Explore objective

This objective is activated by the subtask mira::navigation::MileageTask. It tries to drive with a maximum given speed and can be used to explore an area. Can be used together with the Mileage objective to stop after a given distance.

Needs a differential robot model to work.

Parameters

RemoteControl objective

Allows to set a velocity the robot should drive, while still e.g. performing obstacle avoidance.

Services

Published

Speed objective

The objective reads regional translation speed limits from a speed map and makes sure the robot observes them. If a VelocityTask is set, it also limits the velocities (translatio nand rotation) accordingly. Limits apply to the absolute values of the robot velocity.

Channels

Subscribed

Parameters

Follow a predefined path

The purpose of the PathFollowObjective is to set an entire path in the task, which the robot will follow point by point.

Channels

Published

Parameters

Set a task

The following examples assume, that the Pilot is located in the namespace /navigation.

Use MiraCenter

In miracenter you can open a 3d view, add visualizations of the used map, the RobotFrame or a visualization of the robot's rigid model and optionally some sensor data (e.g. laser). This will give you an idea of where the robot is localized in the map. Then select the GoalTool and click at a point in the map (note: the position must be reachable, free and not be located in a nogo area). The robot will start navigating to the selected position. You can change the GoalTool's preferences in the 3D view's property editor (Visualization Control), in General->Tools.

Use the C++ RPC interface

To set a task one needs to create a "task container" and add one or more subtasks (see The task based system). The required headers for the different tasks can be found in the toolbox Navigation, so you need to add MIRA_REQUIRE_PACKAGE(Navigation) to your package or CMake file and link against the lib Navigation.

In the following example we create a task that will send the robot to position x:0 and y:5 (with a tolerance of 0.3 - 0.2 meter) facing direction 180° (with a tolerance of 15°) when reaching this point. Additionally we only want to allow forward motion. The example code assumes that it is placed somewhere inside a Unit or MicroUnit class.

#include <fw/MicroUnit.h>
using namespace mira::navigation;
...
class MyUnit : public MicroUnit {
...
void setTask()
{
TaskPtr task(new Task());
task->addSubTask(SubTaskPtr(new PositionTask(Point2f(0.0f, 5.0f), 0.2f, 0.3f)));
task->addSubTask(SubTaskPtr(new OrientationTask(deg2rad(180.0f), deg2rad(15.0f))));
callService<void>("/navigation/Pilot", "setTask", task);
}
...
};

If the namespace of the Pilot service is unknown, the following code can be used to discover the INavigation interface:

void setTask()
{
TaskPtr task(new Task());
...
// Get the navigation service
auto providers = queryServicesForInterface("INavigation");
if(providers.empty())
return;
// Assume that our Pilot is the first and only available INavigation provider.
const std::string service = providers.front();
// Let the robot move
auto rpcFuture = authority->callService<void>(service, "setTask", task);
// Get the result, even though it is void. If an exception has occurred, this will throw as well.
rpcFuture.get();
}

Use the RPC console

Within miracenter, the RPC console can be used to set a new task.

The simplest way to set a new goal is to use the setGoal method:

/navigation/Pilot.setGoal({ "X": 0.0, "Y": 5.0, "Phi": 180.0 }, 0.2, 0.3)

Furthermore, also the method setTask can be used:

/navigation/Pilot.setTask({
"SubTasks" : [
{
"@class" : "mira::navigation::PositionTask",
"MaxTolerance" : 0.2,
"MinTolerance" : 0.1,
"Position" : {
"X" : 2.0,
"Y" : 0.0
}
},
{
"@class" : "mira::navigation::OrientationTask",
"Orientation" : 180,
"Tolerance" : 15
},
{
"@class" : "mira::navigation::PreferredDirectionTask",
"Direction" : 1,
"WrongDirectionCost" : 0.5
}
]
})

(Please note: The example above must be put into one line in the RPC console!)

Use the JSON RPC interface

The JSON-RPC interface can be used via the WebServer (e.g. JavaScript) or via the RPCView or RPCConsole in miracenter. To set a task one needs to create a "task container" and add one or more subtasks (see The task based system). In the following example we create a task that will send the robot to position x:0 and y:5 (with a tolerance of 0.3 - 0.2 meter) facing direction 180° (with a tolerance of 15°) when reaching this point. Additionally we only want to allow forward motion.

method = "/navigation/Pilot.setTask";
param = {"SubTasks" : [
{
"@class" : "mira::navigation::PositionTask",
"MaxTolerance" : 0.3,
"MinTolerance" : 0.2,
"Position" : {"X" : 0.0,"Y" : 5.0}
},
{
"@class" : "mira::navigation::OrientationTask",
"Orientation" : 180,
"Tolerance" : 15.0
},
{
"@class" : "mira::navigation::PreferredDirectionTask",
"Direction" : 1,
"WrongDirectionCost" : 0.5
}
]};
callService(method, JSON.stringify(param));