ackermann: refactor code architecture

This commit is contained in:
chfriedrich98
2025-02-10 15:54:24 +01:00
committed by Silvan Fuhrer
parent ce64263ce7
commit 55f51d7e7e
40 changed files with 2418 additions and 1337 deletions
+1
View File
@@ -70,6 +70,7 @@ add_subdirectory(pure_pursuit EXCLUDE_FROM_ALL)
add_subdirectory(rate_control EXCLUDE_FROM_ALL)
add_subdirectory(rc EXCLUDE_FROM_ALL)
add_subdirectory(ringbuffer EXCLUDE_FROM_ALL)
add_subdirectory(rover_control EXCLUDE_FROM_ALL)
add_subdirectory(rtl EXCLUDE_FROM_ALL)
add_subdirectory(sensor_calibration EXCLUDE_FROM_ALL)
add_subdirectory(slew_rate EXCLUDE_FROM_ALL)
+41
View File
@@ -0,0 +1,41 @@
############################################################################
#
# Copyright (c) 2024 PX4 Development Team. 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, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
px4_add_library(rover_control
RoverControl.cpp
RoverControl.hpp
)
target_link_libraries(rover_control PUBLIC PID)
target_link_libraries(rover_control PUBLIC geo)
px4_add_unit_gtest(SRC RoverControlTest.cpp LINKLIBS rover_control)
+214
View File
@@ -0,0 +1,214 @@
/****************************************************************************
*
* Copyright (c) 2025 PX4 Development Team. 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, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#include "RoverControl.hpp"
using namespace matrix;
namespace RoverControl
{
float throttleControl(SlewRate<float> &motor_setpoint, const float throttle_setpoint,
const float current_motor_setpoint, const float max_accel, const float max_decel, const float max_thr_spd,
const float dt)
{
// Sanitize inputs
if (!PX4_ISFINITE(throttle_setpoint) || !PX4_ISFINITE(current_motor_setpoint) || !PX4_ISFINITE(dt)) {
return NAN;
}
const bool accelerating = fabsf(throttle_setpoint) > fabsf(current_motor_setpoint);
if (accelerating && max_accel > FLT_EPSILON && max_thr_spd > FLT_EPSILON) { // Acceleration slew rate
motor_setpoint.setSlewRate(max_accel / max_thr_spd);
// Reinitialize slew rate if current value is closer to setpoint than post slew rate value
if (fabsf(motor_setpoint.getState() - current_motor_setpoint) > fabsf(throttle_setpoint -
current_motor_setpoint)) {
motor_setpoint.setForcedValue(current_motor_setpoint);
}
motor_setpoint.update(throttle_setpoint, dt);
} else if (!accelerating && max_decel > FLT_EPSILON && max_thr_spd > FLT_EPSILON) { // Deceleration slew rate
motor_setpoint.setSlewRate(max_decel / max_thr_spd);
// Reinitialize slew rate if current value is closer to setpoint than post slew rate value
if (fabsf(motor_setpoint.getState() - current_motor_setpoint) > fabsf(throttle_setpoint -
current_motor_setpoint)) {
motor_setpoint.setForcedValue(current_motor_setpoint);
}
motor_setpoint.update(throttle_setpoint, dt);
} else { // Fallthrough if slew rate parameters are not configured
motor_setpoint.setForcedValue(throttle_setpoint);
}
return motor_setpoint.getState();
}
float attitudeControl(SlewRateYaw<float> &adjusted_yaw_setpoint, PID &pid_yaw,
const float yaw_slew_rate, float vehicle_yaw, float yaw_setpoint, const float dt)
{
// Sanitize inputs
if (!PX4_ISFINITE(yaw_setpoint) || !PX4_ISFINITE(vehicle_yaw) || !PX4_ISFINITE(dt)) {
return NAN;
}
yaw_setpoint = wrap_pi(yaw_setpoint);
vehicle_yaw = wrap_pi(vehicle_yaw);
if (yaw_slew_rate > FLT_EPSILON) { // Apply slew rate if configured
adjusted_yaw_setpoint.setSlewRate(yaw_slew_rate);
// Reinitialize slew rate if current value is closer to setpoint than post slew rate value
if (fabsf(wrap_pi(adjusted_yaw_setpoint.getState() - vehicle_yaw)) > fabsf(wrap_pi(yaw_setpoint - vehicle_yaw))) {
adjusted_yaw_setpoint.setForcedValue(vehicle_yaw);
}
adjusted_yaw_setpoint.update(yaw_setpoint, dt);
} else {
adjusted_yaw_setpoint.setForcedValue(yaw_setpoint);
}
// Feedback control
pid_yaw.setSetpoint(
wrap_pi(adjusted_yaw_setpoint.getState() - vehicle_yaw)); // Error as setpoint to take care of wrapping
return pid_yaw.update(0.f, dt);
}
float speedControl(SlewRate<float> &speed_with_rate_limit, PID &pid_speed, const float speed_setpoint,
const float vehicle_speed, const float max_accel, const float max_decel, const float max_thr_speed, const float dt)
{
// Sanitize inputs
if (!PX4_ISFINITE(speed_setpoint) || !PX4_ISFINITE(vehicle_speed) || !PX4_ISFINITE(dt)) {
return NAN;
}
// Apply acceleration and deceleration limit
if (fabsf(speed_setpoint) >= fabsf(vehicle_speed) && max_accel > FLT_EPSILON) {
speed_with_rate_limit.setSlewRate(max_accel);
// Reinitialize slew rate if current value is closer to setpoint than post slew rate value
if (fabsf(speed_with_rate_limit.getState() - vehicle_speed) > fabsf(
speed_setpoint - vehicle_speed)) {
speed_with_rate_limit.setForcedValue(vehicle_speed);
}
speed_with_rate_limit.update(speed_setpoint, dt);
} else if (fabsf(speed_setpoint) < fabsf(vehicle_speed) && max_decel > FLT_EPSILON) {
speed_with_rate_limit.setSlewRate(max_decel);
// Reinitialize slew rate if current value is closer to setpoint than post slew rate value
if (fabsf(speed_with_rate_limit.getState() - vehicle_speed) > fabsf(
speed_setpoint - vehicle_speed)) {
speed_with_rate_limit.setForcedValue(vehicle_speed);
}
speed_with_rate_limit.update(speed_setpoint, dt);
} else { // Fallthrough if slew rate is not configured
speed_with_rate_limit.setForcedValue(speed_setpoint);
}
// Calculate normalized forward speed setpoint
float forward_speed_normalized{0.f};
// Feedforward
if (max_thr_speed > FLT_EPSILON) {
forward_speed_normalized = math::interpolate<float>(speed_with_rate_limit.getState(),
-max_thr_speed, max_thr_speed,
-1.f, 1.f);
}
// Feedback control
pid_speed.setSetpoint(speed_with_rate_limit.getState());
forward_speed_normalized += pid_speed.update(vehicle_speed, dt);
return math::constrain(forward_speed_normalized, -1.f, 1.f);
}
void globalToLocalSetpointTriplet(Vector2f &curr_wp_ned, Vector2f &prev_wp_ned, Vector2f &next_wp_ned,
position_setpoint_triplet_s position_setpoint_triplet, Vector2f &curr_pos_ned, Vector2d &home_pos,
MapProjection &global_ned_proj_ref)
{
if (position_setpoint_triplet.current.valid && PX4_ISFINITE(position_setpoint_triplet.current.lat)
&& PX4_ISFINITE(position_setpoint_triplet.current.lon)) {
curr_wp_ned = global_ned_proj_ref.project(position_setpoint_triplet.current.lat, position_setpoint_triplet.current.lon);
} else {
curr_wp_ned = curr_pos_ned.isAllFinite() ? curr_pos_ned : Vector2f(NAN, NAN); // Fallback if current waypoint is invalid
}
if (position_setpoint_triplet.previous.valid && PX4_ISFINITE(position_setpoint_triplet.previous.lat)
&& PX4_ISFINITE(position_setpoint_triplet.previous.lon)) {
prev_wp_ned = global_ned_proj_ref.project(position_setpoint_triplet.previous.lat,
position_setpoint_triplet.previous.lon);
} else {
prev_wp_ned = curr_pos_ned.isAllFinite() ? curr_pos_ned : Vector2f(NAN,
NAN); // Fallback if previous waypoint is invalid
}
if (position_setpoint_triplet.next.valid && PX4_ISFINITE(position_setpoint_triplet.next.lat)
&& PX4_ISFINITE(position_setpoint_triplet.next.lon)) {
next_wp_ned = global_ned_proj_ref.project(position_setpoint_triplet.next.lat, position_setpoint_triplet.next.lon);
} else {
next_wp_ned = home_pos.isAllFinite() ? global_ned_proj_ref.project(home_pos(0), home_pos(1)) : Vector2f(NAN,
NAN); // Enables corner slow down with RTL
}
}
float calcWaypointTransitionAngle(Vector2f &prev_wp_ned, Vector2f &curr_wp_ned, Vector2f &next_wp_ned)
{
// Sanitize inputs
if (!prev_wp_ned.isAllFinite() || !curr_wp_ned.isAllFinite() || !next_wp_ned.isAllFinite()) {
return NAN;
}
const Vector2f curr_to_next_wp_ned = next_wp_ned - curr_wp_ned;
const Vector2f curr_to_prev_wp_ned = prev_wp_ned - curr_wp_ned;
// Waypoint overlap
if (curr_to_next_wp_ned.norm() < FLT_EPSILON || curr_to_prev_wp_ned.norm() < FLT_EPSILON) {
return NAN;
}
float cosin = curr_to_prev_wp_ned.unit_or_zero() * curr_to_next_wp_ned.unit_or_zero();
cosin = math::constrain<float>(cosin, -1.f, 1.f); // Protect against float precision problem
return acosf(cosin);
}
} // RoverControl
+118
View File
@@ -0,0 +1,118 @@
/****************************************************************************
*
* Copyright (c) 2025 PX4 Development Team. 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, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file RoverControl.hpp
*
* Functions that are shared among the different rover modules.
* Also includes the parameters that are shared among the rover modules.
*/
#pragma once
#include <lib/slew_rate/SlewRate.hpp>
#include <lib/slew_rate/SlewRateYaw.hpp>
#include <lib/pid/PID.hpp>
#include <matrix/matrix/math.hpp>
#include <uORB/topics/position_setpoint_triplet.h>
#include <lib/geo/geo.h>
using namespace matrix;
namespace RoverControl
{
/**
* Applies acceleration/deceleration slew rate to a throttle setpoint.
* @param motor_setpoint Throttle setpoint with applied slew rate [-1, 1] (Updated by this function)
* @param throttle_setpoint Throttle setpoint pre slew rate [-1, 1]
* @param current_motor_setpoint Currently applied motor input [-1, 1]
* @param max_accel Maximum allowed acceleration [m/s^2]
* @param max_decel Maximum allowed deceleration [m/s^2]
* @param max_thr_spd Speed the rover drives at maximum throttle [m/s]
* @param dt Time since last update [s]
* @return Motor Setpoint [-1, 1]
*/
float throttleControl(SlewRate<float> &motor_setpoint, float throttle_setpoint, float current_motor_setpoint,
float max_accel, float max_decel, float max_thr_spd, float dt);
/**
* Applies yaw rate slew rate to a yaw setpoint and calculates the necessary yaw rate setpoint
* using a PID controller.
* @param adjusted_yaw_setpoint Yaw setpoint with applied slew rate [-1, 1] (Updated by this function)
* @param pid_yaw Yaw PID (Updated by this function)
* @param yaw_slew_rate Yaw slew rate [rad/s]
* @param vehicle_yaw Measured vehicle yaw [rad]
* @param yaw_setpoint Yaw setpoint [rad]
* @param dt Time since last update [s]
* @return Yaw rate setpoint [rad/s]
*/
float attitudeControl(SlewRateYaw<float> &adjusted_yaw_setpoint, PID &pid_yaw, float yaw_slew_rate,
float vehicle_yaw, float yaw_setpoint, float dt);
/**
* Applies acceleration/deceleration slew rate to a speed setpoint and calculates the necessary throttle setpoint
* using a feed forward term and PID controller.
* @param speed_with_rate_limit Speed setpoint with applied slew rate [-1, 1] (Updated by this function)
* @param pid_speed Speed PID (Updated by this function)
* @param speed_setpoint Speed setpoint [m/s]
* @param vehicle_speed Measured vehicle speed [m/s]
* @param max_accel Maximum allowed acceleration [m/s^2]
* @param max_decel Maximum allowed deceleration [m/s^2]
* @param max_thr_speed Speed at maximum throttle [m/s]
* @param dt Time since last update [s]
* @return Throttle setpoint [-1, 1]
*/
float speedControl(SlewRate<float> &speed_with_rate_limit, PID &pid_speed, float speed_setpoint,
float vehicle_speed, float max_accel, float max_decel, float max_thr_speed, float dt);
/**
* Projects positionSetpointTriplet waypoints from global to ned frame.
* @param curr_wp_ned Current waypoint in NED frame (Updated by this function)
* @param prev_wp_ned Previous waypoint in NED frame (Updated by this function)
* @param next_wp_ned Next waypoint in NED frame (Updated by this function)
* @param position_setpoint_triplet Position Setpoint Triplet
* @param curr_pos Current position of the rover in global frame
* @param home_pos Home position in global frame
* @param global_ned_proj_ref Global to ned projection
*/
void globalToLocalSetpointTriplet(Vector2f &curr_wp_ned, Vector2f &prev_wp_ned, Vector2f &next_wp_ned,
position_setpoint_triplet_s position_setpoint_triplet, Vector2f &curr_pos_ned, Vector2d &home_pos,
MapProjection &global_ned_proj_ref);
/**
* Calculate and return the angle between the prevWP-currWP and currWP-nextWP line segments [rad]
* @param prev_wp_ned Previous waypoint in NED frame
* @param curr_wp_ned Current waypoint in NED frame
* @param next_wp_ned Next waypoint in NED frame
* @return Waypoint transition angle [rad]
*/
float calcWaypointTransitionAngle(Vector2f &prev_wp_ned, Vector2f &curr_wp_ned, Vector2f &next_wp_ned);
}
+115
View File
@@ -0,0 +1,115 @@
/****************************************************************************
*
* Copyright (C) 2025 PX4 Development Team. 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, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/******************************************************************
* Test code for the Pure Pursuit algorithm
* Run this test only using "make tests TESTFILTER=RoverControl"
******************************************************************/
#include <gtest/gtest.h>
#include "RoverControl.hpp"
TEST(calcWaypointTransitionAngle, invalidInputs)
{
Vector2f prev_wp_ned(NAN, NAN);
Vector2f curr_wp_ned(10.f, 10.f);
Vector2f next_wp_ned(10.f, 10.f);
float prevInvalid = RoverControl::calcWaypointTransitionAngle(prev_wp_ned, curr_wp_ned, next_wp_ned);
prev_wp_ned = Vector2f(10.f, 10.f);
curr_wp_ned = Vector2f(NAN, NAN);
float currInvalid = RoverControl::calcWaypointTransitionAngle(prev_wp_ned, curr_wp_ned, next_wp_ned);
curr_wp_ned = Vector2f(10.f, 10.f);
next_wp_ned = Vector2f(NAN, NAN);
float nextInvalid = RoverControl::calcWaypointTransitionAngle(prev_wp_ned, curr_wp_ned, next_wp_ned);
EXPECT_FALSE(PX4_ISFINITE(prevInvalid));
EXPECT_FALSE(PX4_ISFINITE(currInvalid));
EXPECT_FALSE(PX4_ISFINITE(nextInvalid));
}
TEST(calcWaypointTransitionAngle, validInputs)
{
// P -- C -- N
Vector2f prev_wp_ned(0.f, 0.f);
Vector2f curr_wp_ned(10.f, 0.f);
Vector2f next_wp_ned(20.f, 0.f);
const float angle1 = RoverControl::calcWaypointTransitionAngle(prev_wp_ned, curr_wp_ned, next_wp_ned);
EXPECT_FLOAT_EQ(angle1, M_PI_F);
/**
* N
* /
* P -- C
*/
prev_wp_ned = Vector2f(0.f, 0.f);
curr_wp_ned = Vector2f(10.f, 0.f);
next_wp_ned = Vector2f(20.f, 10.f);
const float angle2 = RoverControl::calcWaypointTransitionAngle(prev_wp_ned, curr_wp_ned, next_wp_ned);
EXPECT_FLOAT_EQ(angle2, M_PI_F - M_PI_4_F);
/**
* N
* |
* P -- C
*/
prev_wp_ned = Vector2f(0.f, 0.f);
curr_wp_ned = Vector2f(10.f, 0.f);
next_wp_ned = Vector2f(10.f, 10.f);
const float angle3 = RoverControl::calcWaypointTransitionAngle(prev_wp_ned, curr_wp_ned, next_wp_ned);
EXPECT_FLOAT_EQ(angle3, M_PI_2_F);
/**
* N
* \
* P -- C
*/
prev_wp_ned = Vector2f(0.f, 0.f);
curr_wp_ned = Vector2f(10.f, 0.f);
next_wp_ned = Vector2f(0.f, 10.f);
const float angle4 = RoverControl::calcWaypointTransitionAngle(prev_wp_ned, curr_wp_ned, next_wp_ned);
EXPECT_FLOAT_EQ(angle4, M_PI_4_F);
// P/C -- N
prev_wp_ned = Vector2f(0.f, 0.f);
curr_wp_ned = Vector2f(0.f, 0.f);
next_wp_ned = Vector2f(10.f, 0.f);
const float angle5 = RoverControl::calcWaypointTransitionAngle(prev_wp_ned, curr_wp_ned, next_wp_ned);
EXPECT_FALSE(PX4_ISFINITE(angle5));
// P -- C/N
prev_wp_ned = Vector2f(0.f, 0.f);
curr_wp_ned = Vector2f(10.f, 0.f);
next_wp_ned = Vector2f(10.f, 0.f);
const float angle6 = RoverControl::calcWaypointTransitionAngle(prev_wp_ned, curr_wp_ned, next_wp_ned);
EXPECT_FALSE(PX4_ISFINITE(angle6));
}
+191
View File
@@ -0,0 +1,191 @@
module_name: Rover Control
parameters:
- group: Rover Control
definitions:
RO_MAX_THR_SPEED:
description:
short: Speed the rover drives at maximum throttle
long: Used to linearly map speeds [m/s] to throttle values [-1. 1].
type: float
unit: m/s
min: 0
max: 100
increment: 0.01
decimal: 2
default: 0
RO_ACCEL_LIM:
description:
short: Acceleration limit
long: |
Set to -1 to disable.
For mecanum rovers this limit is used for longitudinal and lateral acceleration.
type: float
unit: m/s^2
min: -1
max: 100
increment: 0.01
decimal: 2
default: -1
RO_DECEL_LIM:
description:
short: Deceleration limit
long: |
Set to -1 to disable.
Note that if it is disabled the rover will not slow down when approaching waypoints in auto modes.
For mecanum rovers this limit is used for longitudinal and lateral deceleration.
type: float
unit: m/s^2
min: -1
max: 100
increment: 0.01
decimal: 2
default: -1
RO_JERK_LIM:
description:
short: Jerk limit
long: |
Set to -1 to disable.
Note that if it is disabled the rover will not slow down when approaching waypoints in auto modes.
For mecanum rovers this limit is used for longitudinal and lateral jerk.
type: float
unit: m/s^3
min: -1
max: 100
increment: 0.01
decimal: 2
default: -1
RO_YAW_RATE_TH:
description:
short: Yaw rate measurement threshold
long: The minimum threshold for the yaw rate measurement not to be interpreted as zero.
type: float
unit: deg/s
min: 0
max: 100
increment: 0.01
decimal: 2
default: 3
RO_SPEED_TH:
description:
short: Speed measurement threshold
long: The minimum threshold for the speed measurement not to be interpreted as zero.
type: float
unit: m/s
min: 0
max: 100
increment: 0.01
decimal: 2
default: 0.1
RO_YAW_STICK_DZ:
description:
short: Yaw stick deadzone
long: Percentage of stick input range that will be interpreted as zero around the stick centered value.
type: float
min: 0
max: 1
increment: 0.01
decimal: 2
default: 0.1
- group: Rover Rate Control
definitions:
RO_YAW_RATE_P:
description:
short: Proportional gain for closed loop yaw rate controller
type: float
min: 0
max: 100
increment: 0.01
decimal: 3
default: 0
RO_YAW_RATE_I:
description:
short: Integral gain for closed loop yaw rate controller
type: float
min: 0
max: 100
increment: 0.01
decimal: 3
default: 0
RO_YAW_RATE_LIM:
description:
short: Yaw rate limit
long: |
Used to cap yaw rate setpoints and map controller inputs to yaw rate setpoints
in Acro, Stabilized and Position mode.
type: float
unit: deg/s
min: 0
max: 10000
increment: 0.01
decimal: 2
default: 0
RO_YAW_ACCEL_LIM:
description:
short: Yaw acceleration limit
long: Set to -1 to disable.
type: float
unit: deg/s^2
min: -1
max: 10000
increment: 0.01
decimal: 2
default: -1
- group: Rover Attitude Control
definitions:
RO_YAW_P:
description:
short: Proportional gain for closed loop yaw controller
type: float
min: 0
max: 100
increment: 0.01
decimal: 3
default: 0
- group: Rover Velocity Control
definitions:
RO_SPEED_P:
description:
short: Proportional gain for ground speed controller
type: float
min: 0
max: 100
increment: 0.01
decimal: 2
default: 0
RO_SPEED_I:
description:
short: Integral gain for ground speed controller
type: float
min: 0
max: 100
increment: 0.001
decimal: 3
default: 0
RO_SPEED_LIM:
description:
short: Speed limit
long: |
Used to cap speed setpoints and map controller inputs to speed setpoints
in Position mode.
type: float
unit: m/s
min: -1
max: 100
increment: 0.01
decimal: 2
default: -1