Skip to content

Commit

Permalink
rover_control: unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chfriedrich98 committed Feb 7, 2025
1 parent 9249606 commit 53c100f
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/lib/rover_control/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@ 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)
6 changes: 6 additions & 0 deletions src/lib/rover_control/RoverControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,12 @@ float calcWaypointTransitionAngle(Vector2f &prev_wp_ned, Vector2f &curr_wp_ned,

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);
Expand Down
115 changes: 115 additions & 0 deletions src/lib/rover_control/RoverControlTest.cpp
Original file line number Diff line number Diff line change
@@ -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));
}

0 comments on commit 53c100f

Please sign in to comment.