//
// Copyright (c) 2015-2018, 2021-2023, 2025-2026 LAAS/CNRS
// All rights reserved.
//
// Redistribution and use  in source  and binary  forms,  with or without
// modification, are permitted provided that the following conditions are
// met:
//
//   1. Redistributions of  source  code must retain the  above copyright
//      notice and this list of conditions.
//   2. Redistributions in binary form must reproduce the above copyright
//      notice and  this list of  conditions in the  documentation and/or
//      other materials provided with the distribution.
//
//                                      Anthony Mallet on Thu May 31 2018
//

// This file was generated from uavpos.gen by the skeleton
// template. Manual changes should be preserved, although they should
// rather be added to the "doc" attributes of the genom objects defined in
// uavpos.gen.

= uavpos component
openrobots@laas.fr
1.4
:toc: left

// fix default asciidoctor stylesheet issue #2407 and add hr clear rule
ifdef::backend-html5[]
[pass]
++++
<link rel="stylesheet" href="data:text/css,p{font-size: inherit !important}" >
<link rel="stylesheet" href="data:text/css,hr{clear: both}" >
++++
endif::[]



== Ports


[[uav_input]]
=== uav_input (out)


[role="small", width="50%", float="right", cols="1"]
|===
a|.Data structure
[disc]
 * `struct ::or_uav::input` `uav_input`
 ** `struct ::or::time::ts` `ts`
 *** `long` `sec`
 *** `long` `nsec`
 ** `boolean` `intrinsic`
 ** `optional< struct ::or::rb3d::force >` `thrust`
 *** `double` `x`
 *** `double` `y`
 *** `double` `z`
 ** `optional< struct ::or::t3d::att >` `att`
 *** `double` `qw`
 *** `double` `qx`
 *** `double` `qy`
 *** `double` `qz`
 ** `optional< struct ::or::t3d::avel >` `avel`
 *** `double` `wx`
 *** `double` `wy`
 *** `double` `wz`
 ** `optional< struct ::or::t3d::aacc >` `aacc`
 *** `double` `awx`
 *** `double` `awy`
 *** `double` `awz`

|===

Attitude/thrust control input.

'''

[[wrench_measure]]
=== wrench_measure (in)


[role="small", width="50%", float="right", cols="1"]
|===
a|.Data structure
[disc]
 * `struct ::or_wrench_estimator::state` `wrench_measure`
 ** `struct ::or::time::ts` `ts`
 *** `long` `sec`
 *** `long` `nsec`
 ** `boolean` `intrinsic`
 ** `optional< struct ::or::rb3d::force >` `force`
 *** `double` `x`
 *** `double` `y`
 *** `double` `z`
 ** `optional< struct ::or::rb3d::force_cov >` `force_cov`
 *** `double` `cov[6]`
 ** `optional< struct ::or::rb3d::torque >` `torque`
 *** `double` `x`
 *** `double` `y`
 *** `double` `z`
 ** `optional< struct ::or::rb3d::torque_cov >` `torque_cov`
 *** `double` `cov[6]`

|===

Provides current wrench measurements.

This port contains the current wrench exerted by the UAV according
to the propeller measurements and the geometric model.

'''

[[state]]
=== state (in)


[role="small", width="50%", float="right", cols="1"]
|===
a|.Data structure
[disc]
 * `struct ::or_pose_estimator::state` `state`
 ** `struct ::or::time::ts` `ts`
 *** `long` `sec`
 *** `long` `nsec`
 ** `boolean` `intrinsic`
 ** `optional< struct ::or::t3d::pos >` `pos`
 *** `double` `x`
 *** `double` `y`
 *** `double` `z`
 ** `optional< struct ::or::t3d::att >` `att`
 *** `double` `qw`
 *** `double` `qx`
 *** `double` `qy`
 *** `double` `qz`
 ** `optional< struct ::or::t3d::vel >` `vel`
 *** `double` `vx`
 *** `double` `vy`
 *** `double` `vz`
 ** `optional< struct ::or::t3d::avel >` `avel`
 *** `double` `wx`
 *** `double` `wy`
 *** `double` `wz`
 ** `optional< struct ::or::t3d::acc >` `acc`
 *** `double` `ax`
 *** `double` `ay`
 *** `double` `az`
 ** `optional< struct ::or::t3d::aacc >` `aacc`
 *** `double` `awx`
 *** `double` `awy`
 *** `double` `awz`
 ** `optional< struct ::or::t3d::pos_cov >` `pos_cov`
 *** `double` `cov[6]`
 ** `optional< struct ::or::t3d::att_cov >` `att_cov`
 *** `double` `cov[10]`
 ** `optional< struct ::or::t3d::att_pos_cov >` `att_pos_cov`
 *** `double` `cov[12]`
 ** `optional< struct ::or::t3d::vel_cov >` `vel_cov`
 *** `double` `cov[6]`
 ** `optional< struct ::or::t3d::avel_cov >` `avel_cov`
 *** `double` `cov[6]`
 ** `optional< struct ::or::t3d::acc_cov >` `acc_cov`
 *** `double` `cov[6]`
 ** `optional< struct ::or::t3d::aacc_cov >` `aacc_cov`
 *** `double` `cov[6]`

|===

'''

[[reference]]
=== reference (in)


[role="small", width="50%", float="right", cols="1"]
|===
a|.Data structure
[disc]
 * `struct ::or_rigid_body::state` `reference`
 ** `struct ::or::time::ts` `ts`
 *** `long` `sec`
 *** `long` `nsec`
 ** `boolean` `intrinsic`
 ** `optional< struct ::or::t3d::pos >` `pos`
 *** `double` `x`
 *** `double` `y`
 *** `double` `z`
 ** `optional< struct ::or::t3d::att >` `att`
 *** `double` `qw`
 *** `double` `qx`
 *** `double` `qy`
 *** `double` `qz`
 ** `optional< struct ::or::t3d::vel >` `vel`
 *** `double` `vx`
 *** `double` `vy`
 *** `double` `vz`
 ** `optional< struct ::or::t3d::avel >` `avel`
 *** `double` `wx`
 *** `double` `wy`
 *** `double` `wz`
 ** `optional< struct ::or::t3d::acc >` `acc`
 *** `double` `ax`
 *** `double` `ay`
 *** `double` `az`
 ** `optional< struct ::or::t3d::aacc >` `aacc`
 *** `double` `awx`
 *** `double` `awy`
 *** `double` `awz`
 ** `optional< struct ::or::t3d::jerk >` `jerk`
 *** `double` `jx`
 *** `double` `jy`
 *** `double` `jz`
 ** `optional< struct ::or::t3d::snap >` `snap`
 *** `double` `sx`
 *** `double` `sy`
 *** `double` `sz`

|===

'''

== Services

[[set_saturation]]
=== set_saturation (attribute)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Inputs
[disc]
 * `struct ::uavpos::ids::servo_s::sat_s` `sat`
 ** `double` `x`
 ** `double` `v`
 ** `double` `ix`

|===

'''

[[set_servo_gain]]
=== set_servo_gain (attribute)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Inputs
[disc]
 * `struct ::uavpos::ids::servo_s::gain_s` `gain`
 ** `double` `Kpxy`
 ** `double` `Kpz`
 ** `double` `Kvxy`
 ** `double` `Kvz`
 ** `double` `Kixy`
 ** `double` `Kiz`

|===

'''

[[set_mass]]
=== set_mass (attribute)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Inputs
[disc]
 * `double` `mass`

|===

'''

[[set_xyradius]]
=== set_xyradius (attribute)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Inputs
[disc]
 * `double` `rxy` Maximum lateral thrust (N)

|===

'''

[[set_emerg]]
=== set_emerg (attribute)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Inputs
[disc]
 * `struct ::uavpos::ids::servo_s::emerg_s` `emerg`
 ** `double` `descent` (default `"0.1"`) Vertical acceleration for emergency descent (m/s²)
 ** `double` `dx` (default `"0.05"`) Position uncertainty threshold (m)
 ** `double` `dv` (default `"0.2"`) Linear velocity uncertainty threshold (m/s)

|===

Set thresholds for emergency descent.

`dx` and `dv` represent the maximum uncertainty tolerated in the
input <<state>> for position (`dx`) and linear velocity (`dv`),
measured as 3 times the standard deviation.
By default, `dx` is 5cm and `dv` 20cm/s. Beyond that threshold, an
emergency descent is started.

As long as the emergency descent is active, the position error or
linear velocity error are cancelled (i.e. the desired roll and pitch
are set to 0) and a vertical acceleration of `descent` (by default
-0.1 m/s²) is requested. The descent is based on the mass only,
with no feedback, as the state is considered invalid.

'''

[[get_servo_parameters]]
=== get_servo_parameters (attribute)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Outputs
[disc]
 * `struct ::uavpos::ids::servo_s` `servo`
 ** `struct ::uavpos::ids::servo_s::sat_s` `sat`
 *** `double` `x`
 *** `double` `v`
 *** `double` `ix`
 ** `struct ::uavpos::ids::servo_s::gain_s` `gain`
 *** `double` `Kpxy`
 *** `double` `Kpz`
 *** `double` `Kvxy`
 *** `double` `Kvz`
 *** `double` `Kixy`
 *** `double` `Kiz`
 ** `struct ::uavpos::ids::servo_s::emerg_s` `emerg`
 *** `double` `descent`
 *** `double` `dx`
 *** `double` `dv`

|===

'''

[[get_body_parameters]]
=== get_body_parameters (attribute)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Outputs
[disc]
 * `struct ::uavpos::ids::body_s` `body`
 ** `double` `mass`
 ** `double` `rxy`

|===

'''

[[get_reference]]
=== get_reference (function)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Outputs
[disc]
 * `struct ::or_rigid_body::state` `reference`
 ** `struct ::or::time::ts` `ts`
 *** `long` `sec`
 *** `long` `nsec`
 ** `boolean` `intrinsic`
 ** `optional< struct ::or::t3d::pos >` `pos`
 *** `double` `x`
 *** `double` `y`
 *** `double` `z`
 ** `optional< struct ::or::t3d::att >` `att`
 *** `double` `qw`
 *** `double` `qx`
 *** `double` `qy`
 *** `double` `qz`
 ** `optional< struct ::or::t3d::vel >` `vel`
 *** `double` `vx`
 *** `double` `vy`
 *** `double` `vz`
 ** `optional< struct ::or::t3d::avel >` `avel`
 *** `double` `wx`
 *** `double` `wy`
 *** `double` `wz`
 ** `optional< struct ::or::t3d::acc >` `acc`
 *** `double` `ax`
 *** `double` `ay`
 *** `double` `az`
 ** `optional< struct ::or::t3d::aacc >` `aacc`
 *** `double` `awx`
 *** `double` `awy`
 *** `double` `awz`
 ** `optional< struct ::or::t3d::jerk >` `jerk`
 *** `double` `jx`
 *** `double` `jy`
 *** `double` `jz`
 ** `optional< struct ::or::t3d::snap >` `snap`
 *** `double` `sx`
 *** `double` `sy`
 *** `double` `sz`

|===

'''

[[servo]]
=== servo (activity)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Throws
[disc]
 * `exception ::uavpos::e_input`

a|.Context
[disc]
  * In task `<<main>>`
  (frequency 1000.0 _Hz_)
  * Reads port `<<reference>>`
|===

Track a desired position

'''

[[set_state]]
=== set_state (function)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Inputs
[disc]
 * `struct ::or::t3d::pos` `pos`: Position
 ** `double` `x`
 ** `double` `y`
 ** `double` `z`

 * `struct ::or::t3d::att` `att`: Orientation
 ** `double` `qw`
 ** `double` `qx`
 ** `double` `qy`
 ** `double` `qz`

 * `struct ::or::t3d::vel` `vel`: Linear velocity
 ** `double` `vx`
 ** `double` `vy`
 ** `double` `vz`

 * `struct ::or::t3d::avel` `avel`: Angular velocity
 ** `double` `wx`
 ** `double` `wy`
 ** `double` `wz`

 * `struct ::or::t3d::acc` `acc`: Acceleration
 ** `double` `ax`
 ** `double` `ay`
 ** `double` `az`

 * `struct ::or::t3d::aacc` `aacc`: Angular acceleration
 ** `double` `awx`
 ** `double` `awy`
 ** `double` `awz`

 * `struct ::or::t3d::jerk` `jerk`: Linear jerk
 ** `double` `jx`
 ** `double` `jy`
 ** `double` `jz`

 * `struct ::or::t3d::snap` `snap`: Linear snap
 ** `double` `sx`
 ** `double` `sy`
 ** `double` `sz`

a|.Context
[disc]
  * Interrupts `<<servo>>`
|===

Set the desired state

'''

[[set_position]]
=== set_position (function)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Inputs
[disc]
 * `double` `x`

 * `double` `y`

 * `double` `z`

 * `double` `yaw`

a|.Context
[disc]
  * Interrupts `<<servo>>`
|===

Set the desired position

'''

[[set_current_position]]
=== set_current_position (activity)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Throws
[disc]
 * `exception ::uavpos::e_input`

a|.Context
[disc]
  * In task `<<main>>`
  (frequency 1000.0 _Hz_)
  * Reads port `<<state>>`
  * Interrupts `<<servo>>`
|===

Set the desired position

'''

[[set_velocity]]
=== set_velocity (function)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Inputs
[disc]
 * `double` `x`

 * `double` `y`

 * `double` `z`

 * `double` `yaw`

a|.Context
[disc]
  * Interrupts `<<servo>>`
|===

Set the desired velocity

The controller will try to reach the given velocity and heading
angular velocity. Note that for safety reasons, a watchdog will
trigger after 500ms and reset the target velocity to zero.

'''

[[hover]]
=== hover (function)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Context
[disc]
  * Interrupts `<<servo>>`
|===

Stop tracking a desired position

This sets the current reference velocity and acceleration to 0,
maintaining the current position and heading. Any dynamic reference
tracking is cancelled (see <<servo>>).

'''

[[reset]]
=== reset (function)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Context
[disc]
  * Interrupts `<<servo>>`
|===

Stop control loop and wait for a new valid reference

This function is meant to reset the controller and stop controlling
the robot. The component returns to the same state as when it is
started, waiting for a first reference state provided either with
<<set_state>>, <<set_position>>, <<set_velocity>> or <<servo>> to
track a dynamic reference.

'''

[[log]]
=== log (function)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Inputs
[disc]
 * `string<64>` `path` (default `"/tmp/uavpos.log"`) Log file name

 * `unsigned long` `decimation` (default `"1"`) Reduced logging frequency

a|.Throws
[disc]
 * `exception ::uavpos::e_sys`
 ** `short` `code`
 ** `string<128>` `what`

|===

Log controller data

'''

[[log_stop]]
=== log_stop (function)


Stop logging

'''

[[log_info]]
=== log_info (function)

[role="small", width="50%", float="right", cols="1"]
|===
a|.Outputs
[disc]
 * `unsigned long` `miss` Missed log entries

 * `unsigned long` `total` Total log entries

|===

Show missed log entries

'''

== Tasks

[[main]]
=== main

[role="small", width="50%", float="right", cols="1"]
|===
a|.Context
[disc]
  * Frequency 1000.0 _Hz_
* Updates port `<<uav_input>>`
* Reads port `<<state>>`
|===

'''
