Follow Reference Behavior
The follow_reference_behavior is part of the
as2_behaviors_motion package in Aerostack2.
This behavior keeps the aircraft tracking a 3D reference point given in any TF
frame and stays running until the action client cancels it. It exposes a
plugin-based architecture so the actual tracking strategy can be selected
at runtime via the plugin_name launch argument, while the action server,
goal validation, TF resolution and platform-state monitoring are shared by
every plugin.
Working Principle
The behavior is split in two layers:
Wrapper (
FollowReferenceBehavior): anas2_behavior::BehaviorServerthat owns the action lifecycle (on_activate/on_modify/on_deactivate/on_pause/on_resume/on_run), validates the incoming goal (the platform must beFLYINGand localization must be available), looks the target frame up in TF and substitutes any zero-valuedmax_speed_*field with the matching default parameter before handing the goal over to the plugin.Plugin (one of the available backends, see below): generates the actual reference and pushes it to the controller through the
as2_motion_reference_handlersAPI. The contract isfollow_reference_base::FollowReferenceBase.
Pipeline per goal:
The wrapper resolves the target frame, fills missing speed limits with the per-axis defaults and forwards the goal to the plugin.
The plugin’s
own_activateaccepts the goal and starts publishing the reference (a position setpoint or a generated trajectory, depending on the backend).Every control cycle the wrapper calls
on_runon the plugin, which either emits a fresh reference or reports a status transition. In normal operation the behavior stays inRUNNINGuntil the action client deactivates it.On cancel / deactivate the plugin commands a hover and the action closes.
The base class also exposes state_callback and platform_info_callback,
called by the wrapper from the self_localization/twist and
platform/info subscriptions, so every plugin sees the same localization
and platform state without re-subscribing.
Available Plugins
The package ships two plugins that implement the
FollowReferenceBase contract. Choose one at launch time through the
plugin_name argument.
follow_reference_plugin_position
Tracks the reference by sending position setpoints to the controller through the
as2::motionReferenceHandlers::PositionMotionhandler. The setpoint is always emitted inearth: the live target is re-resolved toearthevery control cycle, which keeps the commanded orientation decoupled from any rotation in the (possibly moving) goal frame.Pause / resume are honoured by sending a hover while paused. Recommended when the controller already produces smooth motion and the platform can handle hard target switches.
follow_reference_plugin_trajectory
Delegates the reference tracking to the Generate Polynomial Trajectory Behavior running in
follow_reference_mode. The plugin sends a single-waypoint goal to the trajectory generator and forwards goal modifications through themotion_reference/modify_waypointtopic. This gives smooth, jerk- or dynamics-aware tracking at the cost of one extra hop through the trajectory generator.The plugin also runs a reactive-modify loop: every cycle it re-resolves the goal target to
earthand republishes amodify_waypointmessage when the target has drifted more thanmodify_thresholdfrom the last published one, rate-limited bymodify_frequency. For static target frames the converted point stays constant and no extra messages are emitted; for moving target frames (e.g. another drone’s body frame) this keeps the trajectory aligned with the live target without action re-issuing.Because the trajectory generator accepts a single scalar
max_speed, the plugin usesmax(max_speed_x, max_speed_y, max_speed_z)and lets the generator distribute that bound across the polynomial axes.
Yaw Policy
The yaw goal is taken from the action yaw field
(as2_msgs/YawMode). Supported modes depend on the active plugin:
Mode |
|
|
|---|---|---|
|
Yes — refreshed every control cycle from the current quaternion. |
Yes — delegated to the trajectory generator. |
|
Yes — uses |
Yes — delegated to the trajectory generator. |
|
Yes — aims the nose from the current position toward the target in
the xy plane; falls back to |
Yes — delegated to the trajectory generator. |
|
Yes — yaws to look at the goal frame origin. |
Yes — delegated to the trajectory generator. |
|
Not supported — the position plugin rejects the goal. |
Yes — handled by the trajectory generator. |
Action Interface
The behavior exposes the action as2_msgs/action/FollowReference on
<namespace>/FollowReferenceBehavior.
Field |
Description |
|---|---|
yaw ( |
Yaw goal mode (see Yaw Policy above). |
target_pose ( |
Reference point. The frame is resolved through TF; an empty
|
max_speed_x / max_speed_y / max_speed_z ( |
Maximum tracking speed per earth axis (m/s). A value of |
Field |
Description |
|---|---|
follow_reference_success ( |
|
Field |
Description |
|---|---|
actual_speed ( |
Current linear speed norm (m/s). |
actual_distance_to_goal ( |
Euclidean distance from the current position to the target, both
expressed in |
Configuration Parameters
The configuration is split in two layers: the wrapper YAML with parameters shared by every plugin, and a plugin-specific block for the trajectory backend.
Wrapper Parameters
Defaults in follow_reference_behavior/config/config_default.yaml.
Parameter |
Default |
Description |
|---|---|---|
follow_reference_max_speed_x |
|
Default maximum tracking speed along the x axis (m/s). Used when the
goal’s |
follow_reference_max_speed_y |
|
Default maximum tracking speed along the y axis (m/s). Used when the
goal’s |
follow_reference_max_speed_z |
|
Default maximum tracking speed along the z axis (m/s). Used when the
goal’s |
tf_timeout_threshold |
|
Timeout (s) consumed by the internal |
follow_reference_plugin_trajectory Parameters
Read only when the trajectory plugin is loaded, under the namespace
follow_reference_plugin_trajectory.*.
Parameter |
Default |
Description |
|---|---|---|
modify_threshold |
|
Translation (m) of the target in |
modify_frequency |
|
Maximum rate (Hz) at which the reactive-modify loop re-publishes
|
Launching the Behavior
The plugin to load is selected through the plugin_name launch argument.
The set of valid choices is auto-populated from the registered plugins via
pluginlib, so an invalid value is rejected at launch time.
ros2 launch as2_behaviors_motion follow_reference_behavior_launch.py \
namespace:=<drone_namespace> \
plugin_name:=follow_reference_plugin_position
Launch arguments:
namespace— drone namespace (defaults to theAEROSTACK2_SIMULATION_DRONE_IDenvironment variable).plugin_name— one offollow_reference_plugin_position,follow_reference_plugin_trajectory. The list is enforced byget_available_plugins('as2_behaviors_motion', 'follow_reference')at launch time.behavior_config_file— path to the behavior YAML (defaults toconfig_default.yaml).log_level— node log level (defaultinfo).use_sim_time— use the simulation clock iftrue(defaultfalse).
Sending a goal manually
ros2 action send_goal /<namespace>/FollowReferenceBehavior \
as2_msgs/action/FollowReference \
"{
yaw: {mode: 0, angle: 0.0},
target_pose: {header: {frame_id: 'earth'},
point: {x: 1.0, y: 0.0, z: 1.0}},
max_speed_x: 1.0,
max_speed_y: 1.0,
max_speed_z: 1.0
}"
The behavior stays in RUNNING until the client cancels the action. While
running, a fresh goal can be sent through on_modify (action client’s
modify request) to retarget without losing the active reference.
Notes
The trajectory plugin re-uses the trajectory generator behavior at
<namespace>/TrajectoryGeneratorBehavior, so both behaviors must be available (and launched) whenplugin_name := follow_reference_plugin_trajectoryis selected.The base class rejects activation if the platform is not
FLYINGor if no localization has been received yet (no twist message onself_localization/twist).