moved ManualVelocitySmoothing to motion_planning lib

Signed-off-by: RomanBapst <bapstroman@gmail.com>
This commit is contained in:
RomanBapst
2021-11-05 18:04:33 +01:00
committed by Silvan Fuhrer
parent 924298e9c3
commit 7cb99f521c
10 changed files with 7 additions and 9 deletions
@@ -40,7 +40,7 @@
#pragma once
#include "FlightTaskManualAltitude.hpp"
#include "ManualVelocitySmoothingZ.hpp"
#include <motion_planning/ManualVelocitySmoothingZ.hpp>
class FlightTaskManualAltitudeSmoothVel : public FlightTaskManualAltitude
{
@@ -40,8 +40,8 @@
#pragma once
#include "FlightTaskManualPosition.hpp"
#include "ManualVelocitySmoothingXY.hpp"
#include "ManualVelocitySmoothingZ.hpp"
#include <motion_planning/ManualVelocitySmoothingXY.hpp>
#include <motion_planning/ManualVelocitySmoothingZ.hpp>
using matrix::Vector2f;
using matrix::Vector3f;
@@ -33,8 +33,6 @@
px4_add_library(FlightTaskUtility
StraightLine.cpp
ManualVelocitySmoothingXY.cpp
ManualVelocitySmoothingZ.cpp
Sticks.cpp
StickAccelerationXY.cpp
StickYaw.cpp
@@ -42,5 +40,3 @@ px4_add_library(FlightTaskUtility
target_link_libraries(FlightTaskUtility PUBLIC FlightTask hysteresis bezier SlewRate motion_planning)
target_include_directories(FlightTaskUtility PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
px4_add_unit_gtest(SRC ManualVelocitySmoothingXYTest.cpp LINKLIBS FlightTaskUtility)
@@ -1,121 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2019 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 "ManualVelocitySmoothingXY.hpp"
#include <mathlib/mathlib.h>
#include <float.h>
using namespace matrix;
void ManualVelocitySmoothingXY::reset(const Vector2f &accel, const Vector2f &vel, const Vector2f &pos)
{
for (int i = 0; i < 2; i++) {
_trajectory[i].reset(accel(i), vel(i), pos(i));
}
resetPositionLock();
}
void ManualVelocitySmoothingXY::resetPositionLock()
{
_position_lock_active = false;
_position_setpoint_locked(0) = NAN;
_position_setpoint_locked(1) = NAN;
}
void ManualVelocitySmoothingXY::update(float dt, const Vector2f &velocity_target)
{
// Update state
updateTrajectories(dt);
// Lock or unlock position
// Has to be done before _updateTrajDurations()
checkPositionLock(velocity_target);
// Update durations and sync XY
updateTrajDurations(velocity_target);
}
void ManualVelocitySmoothingXY::updateTrajectories(float dt)
{
for (int i = 0; i < 2; ++i) {
_trajectory[i].updateTraj(dt);
_state.j(i) = _trajectory[i].getCurrentJerk();
_state.a(i) = _trajectory[i].getCurrentAcceleration();
_state.v(i) = _trajectory[i].getCurrentVelocity();
_state.x(i) = _trajectory[i].getCurrentPosition();
}
}
void ManualVelocitySmoothingXY::updateTrajDurations(const Vector2f &velocity_target)
{
for (int i = 0; i < 2; ++i) {
_trajectory[i].updateDurations(velocity_target(i));
}
VelocitySmoothing::timeSynchronization(_trajectory, 2);
}
void ManualVelocitySmoothingXY::checkPositionLock(const Vector2f &velocity_target)
{
/**
* During a position lock -> position unlock transition, we have to make sure that the velocity setpoint
* is continuous. We know that the output of the position loop (part of the velocity setpoint)
* will suddenly become null
* and only the feedforward (generated by this flight task) will remain.
* This is why the previous input of the velocity controller
* is used to set current velocity of the trajectory.
*/
if (_state.v.length() < 0.1f &&
_state.a.length() < .2f &&
velocity_target.length() <= FLT_EPSILON) {
// Lock position
_position_lock_active = true;
_position_setpoint_locked = _state.x;
} else {
// Unlock position
if (_position_lock_active) {
// Start the trajectory at the current velocity setpoint
_trajectory[0].setCurrentVelocity(_velocity_setpoint_feedback(0));
_trajectory[1].setCurrentVelocity(_velocity_setpoint_feedback(1));
_state.v = _velocity_setpoint_feedback;
resetPositionLock();
}
_trajectory[0].setCurrentPosition(_position_estimate(0));
_trajectory[1].setCurrentPosition(_position_estimate(1));
}
}
@@ -1,126 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2019 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 ManualVelocitySmoothingXY.hpp
*
*/
#pragma once
#include <motion_planning/VelocitySmoothing.hpp>
#include <matrix/matrix/math.hpp>
using matrix::Vector2f;
class ManualVelocitySmoothingXY final
{
public:
ManualVelocitySmoothingXY() = default;
~ManualVelocitySmoothingXY() = default;
void reset(const Vector2f &accel, const Vector2f &vel, const Vector2f &pos);
void update(float dt, const Vector2f &velocity_target);
void setVelSpFeedback(const Vector2f &fb) { _velocity_setpoint_feedback = fb; }
void setMaxJerk(const float max_jerk)
{
_trajectory[0].setMaxJerk(max_jerk);
_trajectory[1].setMaxJerk(max_jerk);
}
float getMaxJerk() const { return _trajectory[0].getMaxJerk(); }
void setMaxAccel(const float max_accel)
{
_trajectory[0].setMaxAccel(max_accel);
_trajectory[1].setMaxAccel(max_accel);
}
float getMaxAccel() const { return _trajectory[0].getMaxAccel(); }
void setMaxVel(const float max_vel)
{
_trajectory[0].setMaxVel(max_vel);
_trajectory[1].setMaxVel(max_vel);
}
float getMaxVel() const { return _trajectory[0].getMaxVel(); }
Vector2f getCurrentJerk() const { return _state.j; }
Vector2f getCurrentAcceleration() const { return _state.a; }
void setCurrentVelocity(const Vector2f &vel)
{
_state.v = vel;
_trajectory[0].setCurrentVelocity(vel(0));
_trajectory[1].setCurrentVelocity(vel(1));
}
Vector2f getCurrentVelocity() const { return _state.v; }
void setCurrentPosition(const Vector2f &pos)
{
_state.x = pos;
_trajectory[0].setCurrentPosition(pos(0));
_trajectory[1].setCurrentPosition(pos(1));
_position_estimate = pos;
if (_position_lock_active) {
_position_setpoint_locked = pos;
}
}
Vector2f getCurrentPosition() const { return _position_setpoint_locked; }
void setCurrentPositionEstimate(const Vector2f &pos) { _position_estimate = pos; }
private:
void resetPositionLock();
void updateTrajectories(float dt);
void checkPositionLock(const Vector2f &velocity_target);
void updateTrajDurations(const Vector2f &velocity_target);
VelocitySmoothing _trajectory[2]; ///< Trajectory in x and y directions
bool _position_lock_active{false};
Vector2f _position_setpoint_locked{};
Vector2f _velocity_setpoint_feedback{};
Vector2f _position_estimate{};
struct {
Vector2f j;
Vector2f a;
Vector2f v;
Vector2f x;
} _state{};
};
@@ -1,87 +0,0 @@
/****************************************************************************
*
* Copyright (C) 2019 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 Manual Velocity Smoothing library
* Run this test only using make tests TESTFILTER=ManualVelocitySmoothing
*/
#include <gtest/gtest.h>
#include <matrix/matrix/math.hpp>
#include "ManualVelocitySmoothingXY.hpp"
using namespace matrix;
class ManualVelocitySmoothingXYTest : public ::testing::Test
{
public:
ManualVelocitySmoothingXY _smoothing;
};
TEST_F(ManualVelocitySmoothingXYTest, setGet)
{
// GIVEN: Some max values
_smoothing.setMaxJerk(11.f);
_smoothing.setMaxAccel(7.f);
_smoothing.setMaxVel(5.f);
// THEN: We should be able to get them back
EXPECT_FLOAT_EQ(_smoothing.getMaxJerk(), 11.f);
EXPECT_FLOAT_EQ(_smoothing.getMaxAccel(), 7.f);
EXPECT_FLOAT_EQ(_smoothing.getMaxVel(), 5.f);
}
TEST_F(ManualVelocitySmoothingXYTest, getCurrentState)
{
// GIVEN: the initial conditions
Vector2f v0(11.f, 13.f);
_smoothing.setCurrentVelocity(v0);
// WHEN: we get the current state
Vector3f j_end;
Vector3f a_end;
Vector3f v_end;
Vector3f x_end;
j_end.xy() = _smoothing.getCurrentJerk();
a_end.xy() = _smoothing.getCurrentAcceleration();
v_end.xy() = _smoothing.getCurrentVelocity();
x_end.xy() = _smoothing.getCurrentPosition();
// THEN: the returned values should match the input
EXPECT_EQ(j_end, Vector3f(0.f, 0.f, 0.f));
EXPECT_EQ(a_end, Vector3f(0.f, 0.f, 0.f));
EXPECT_EQ(v_end, Vector3f(11.f, 13.f, 0.f));
EXPECT_EQ(x_end, Vector3f(0.f, 0.f, 0.f));
}
@@ -1,119 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2019 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 "ManualVelocitySmoothingZ.hpp"
#include <mathlib/mathlib.h>
#include <float.h>
void ManualVelocitySmoothingZ::reset(float accel, float vel, float pos)
{
_trajectory.reset(accel, vel, pos);
resetPositionLock();
}
void ManualVelocitySmoothingZ::resetPositionLock()
{
_position_lock_active = false;
_position_setpoint_locked = NAN;
}
void ManualVelocitySmoothingZ::update(float dt, float velocity_target)
{
// Update state
updateTrajectories(dt);
// Set max accel/vel/jerk
// Has to be done before _updateTrajDurations()
updateTrajConstraints(velocity_target);
// Lock or unlock position
// Has to be done before _updateTrajDurations()
checkPositionLock(velocity_target);
// Update durations
_trajectory.updateDurations(velocity_target);
}
void ManualVelocitySmoothingZ::updateTrajectories(float dt)
{
_trajectory.updateTraj(dt);
_state.j = _trajectory.getCurrentJerk();
_state.a = _trajectory.getCurrentAcceleration();
_state.v = _trajectory.getCurrentVelocity();
_state.x = _trajectory.getCurrentPosition();
}
void ManualVelocitySmoothingZ::updateTrajConstraints(float velocity_target)
{
if (velocity_target < 0.f) { // up
_trajectory.setMaxAccel(_max_accel_up);
_trajectory.setMaxVel(_max_vel_up);
} else { // down
_trajectory.setMaxAccel(_max_accel_down);
_trajectory.setMaxVel(_max_vel_down);
}
}
void ManualVelocitySmoothingZ::checkPositionLock(float velocity_target)
{
/**
* During a position lock -> position unlock transition, we have to make sure that the velocity setpoint
* is continuous. We know that the output of the position loop (part of the velocity setpoint)
* will suddenly become null
* and only the feedforward (generated by this flight task) will remain.
* This is why the previous input of the velocity controller
* is used to set current velocity of the trajectory.
*/
if (fabsf(_state.v) < 0.1f &&
fabsf(_state.a) < .2f &&
fabsf(velocity_target) <= FLT_EPSILON) {
// Lock position
_position_lock_active = true;
_position_setpoint_locked = _state.x;
} else {
// Unlock position
if (_position_lock_active) {
// Start the trajectory at the current velocity setpoint
_trajectory.setCurrentVelocity(_velocity_setpoint_feedback);
_state.v = _velocity_setpoint_feedback;
resetPositionLock();
}
_trajectory.setCurrentPosition(_position_estimate);
}
}
@@ -1,123 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2019 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 ManualVelocitySmoothingZ.hpp
*
*/
#pragma once
#include <motion_planning/VelocitySmoothing.hpp>
class ManualVelocitySmoothingZ final
{
public:
ManualVelocitySmoothingZ() = default;
~ManualVelocitySmoothingZ() = default;
void reset(float accel, float vel, float pos);
void update(float dt, float velocity_target);
void setVelSpFeedback(const float fb) { _velocity_setpoint_feedback = fb; }
void setMaxJerk(const float max_jerk)
{
_trajectory.setMaxJerk(max_jerk);
}
void setMaxAccelUp(const float max_accel_up)
{
_max_accel_up = max_accel_up;
}
void setMaxAccelDown(const float max_accel_down)
{
_max_accel_down = max_accel_down;
}
void setMaxVelUp(const float max_vel_up)
{
_max_vel_up = max_vel_up;
}
void setMaxVelDown(const float max_vel_down)
{
_max_vel_down = max_vel_down;
}
float getCurrentJerk() const { return _state.j; }
float getCurrentAcceleration() const { return _state.a; }
void setCurrentVelocity(const float vel)
{
_state.v = vel;
_trajectory.setCurrentVelocity(vel);
}
float getCurrentVelocity() const { return _state.v; }
void setCurrentPosition(const float pos)
{
_state.x = pos;
_trajectory.setCurrentPosition(pos);
_position_estimate = pos;
if (_position_lock_active) {
_position_setpoint_locked = pos;
}
}
float getCurrentPosition() const { return _position_setpoint_locked; }
void setCurrentPositionEstimate(float pos) { _position_estimate = pos; }
private:
void resetPositionLock();
void updateTrajectories(float dt);
void updateTrajConstraints(float vel_target);
void checkPositionLock(float velocity_target);
void updateTrajDurations(float velocity_target);
VelocitySmoothing _trajectory; ///< Trajectory in z direction
bool _position_lock_active{false};
float _position_setpoint_locked{};
float _velocity_setpoint_feedback{};
float _position_estimate{};
struct {
float j;
float a;
float v;
float x;
} _state{};
float _max_accel_up{0.f};
float _max_accel_down{0.f};
float _max_vel_up{0.f};
float _max_vel_down{0.f};
};