Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
768ef15
Add additional tests
wittenator Mar 1, 2025
e22df84
Merge branch 'ros-controls:master' into master
wittenator Mar 1, 2025
36bc9d5
Remove twist_input from closed loop odometry calculation
wittenator Mar 1, 2025
94eebd0
Merge branch 'ros-controls:master' into master
wittenator Mar 1, 2025
c0f103e
Add in missing test case
wittenator Mar 1, 2025
0564ada
Merge branch 'master' of github.com:wittenator/ros2_controllers
wittenator Mar 1, 2025
eaebf09
Fixed comment
wittenator Mar 1, 2025
3e84edd
Update on ackermann message
wittenator Mar 1, 2025
4f14831
Merge branch 'master' into master
wittenator Mar 3, 2025
e20e63c
Merge branch 'master' into master
wittenator Mar 4, 2025
031ddc6
Merge branch 'master' into master
christophfroehlich Mar 19, 2025
7564e34
Merge branch 'master' into master
wittenator Apr 6, 2025
0c3ded5
Fix reference name
wittenator Apr 6, 2025
a15dc7f
Merge branch 'master' of github.com:wittenator/ros2_controllers
wittenator Apr 6, 2025
66effcf
Merge branch 'ros-controls:master' into master
wittenator Apr 10, 2025
d204e7e
Fix typo
wittenator Apr 10, 2025
948b67c
Merge branch 'master' of github.com:wittenator/ros2_controllers
wittenator Apr 10, 2025
c612f3c
Fix tests
wittenator Apr 10, 2025
915e3bd
Fix exported interfaces tests
wittenator Apr 11, 2025
b038514
Add comment
wittenator Apr 11, 2025
b79d682
Ran precommit hooks
wittenator Apr 11, 2025
f9f2459
Fix all pre-commit checks
wittenator Apr 11, 2025
3782090
Update function description
wittenator Apr 11, 2025
aae242d
Merge branch 'ros-controls:master' into master
wittenator Apr 12, 2025
abbe4fd
Fix missed readability issue
wittenator Apr 14, 2025
fc881c2
Merge branch 'master' of github.com:wittenator/ros2_controllers
wittenator Apr 14, 2025
5a6e60e
Switch from double to float for drive messages in tests
wittenator Apr 14, 2025
ed3ef21
Explicitly cast default parameters to float
wittenator Apr 14, 2025
8b65ff9
Merge branch 'ros-controls:master' into master
wittenator Apr 17, 2025
976935a
Merge branch 'master' into master
wittenator Apr 24, 2025
bb27729
Fixed tests again
wittenator Apr 26, 2025
b42d13a
Merge branch 'ros-controls:master' into master
wittenator Apr 26, 2025
c367db2
Merge branch 'master' into master
wittenator Apr 27, 2025
3436bb0
Merge branch 'master' into master
wittenator Apr 27, 2025
8d9cc8e
Merge branch 'ros-controls:master' into master
wittenator May 18, 2025
8a60aa3
Renamed message naming
wittenator May 18, 2025
f159c60
Merge remote-tracking branch 'origin/master' into wittenator/master
christophfroehlich May 28, 2025
1fd197c
Merge branch 'ros-controls:master' into master
wittenator Jun 9, 2025
9c8bb76
Rename various tests and variables
wittenator Jun 9, 2025
f150a9b
Merge commit
wittenator Jun 9, 2025
d01dd0f
Merge branch 'master' of github.com:wittenator/ros2_controllers
wittenator Jun 12, 2025
1b7cf57
Fix formatting
wittenator Jun 12, 2025
990d2fe
Merge branch 'master' into master
wittenator Jun 12, 2025
ef29f5f
Added consistent naming in tests and fixed docs
wittenator Jun 12, 2025
9d8bd04
Merge branch 'master' of github.com:wittenator/ros2_controllers
wittenator Jun 12, 2025
aebb8be
Merge remote-tracking branch 'upstream/master'
wittenator Aug 11, 2025
39dafe9
fix tests
wittenator Aug 11, 2025
ed7a782
Format with precommit
wittenator Aug 11, 2025
3f64a4d
Merge branch 'ros-controls:master' into master
wittenator Sep 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,13 @@ TEST_F(AckermannSteeringControllerTest, activate_success)
ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS);

// check that the message is reset
auto msg = controller_->input_ref_twist_.readFromNonRT();
EXPECT_TRUE(std::isnan((*msg)->twist.linear.x));
EXPECT_TRUE(std::isnan((*msg)->twist.linear.y));
EXPECT_TRUE(std::isnan((*msg)->twist.linear.z));
EXPECT_TRUE(std::isnan((*msg)->twist.angular.x));
EXPECT_TRUE(std::isnan((*msg)->twist.angular.y));
EXPECT_TRUE(std::isnan((*msg)->twist.angular.z));
auto msg = controller_->input_ref_twist_.get();
EXPECT_TRUE(std::isnan(msg.twist.linear.x));
EXPECT_TRUE(std::isnan(msg.twist.linear.y));
EXPECT_TRUE(std::isnan(msg.twist.linear.z));
EXPECT_TRUE(std::isnan(msg.twist.angular.x));
EXPECT_TRUE(std::isnan(msg.twist.angular.y));
EXPECT_TRUE(std::isnan(msg.twist.angular.z));
}

TEST_F(AckermannSteeringControllerTest, update_success)
Expand Down Expand Up @@ -161,11 +161,11 @@ TEST_F(AckermannSteeringControllerTest, test_update_logic)
ASSERT_FALSE(controller_->is_in_chained_mode());

// set command statically
std::shared_ptr<ControllerReferenceMsg> msg = std::make_shared<ControllerReferenceMsg>();
msg->header.stamp = controller_->get_node()->now();
msg->twist.linear.x = 0.1;
msg->twist.angular.z = 0.2;
controller_->input_ref_twist_.writeFromNonRT(msg);
ControllerReferenceMsg msg;
msg.header.stamp = controller_->get_node()->now();
msg.twist.linear.x = 0.1;
msg.twist.angular.z = 0.2;
controller_->input_ref_twist_.set(msg);

ASSERT_EQ(
controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)),
Expand All @@ -185,7 +185,7 @@ TEST_F(AckermannSteeringControllerTest, test_update_logic)
controller_->command_interfaces_[CMD_STEER_LEFT_WHEEL].get_optional().value(),
1.4179821977774734, COMMON_THRESHOLD);

EXPECT_FALSE(std::isnan((*(controller_->input_ref_twist_.readFromRT()))->twist.linear.x));
EXPECT_FALSE(std::isnan(controller_->input_ref_twist_.get().twist.linear.x));
EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size());
for (const auto & interface : controller_->reference_interfaces_)
{
Expand Down Expand Up @@ -225,7 +225,7 @@ TEST_F(AckermannSteeringControllerTest, test_update_logic_chained)
controller_->command_interfaces_[STATE_STEER_LEFT_WHEEL].get_optional().value(),
1.4179821977774734, COMMON_THRESHOLD);

EXPECT_TRUE(std::isnan((*(controller_->input_ref_twist_.readFromRT()))->twist.linear.x));
EXPECT_TRUE(std::isnan(controller_->input_ref_twist_.get().twist.linear.x));
EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size());
for (const auto & interface : controller_->reference_interfaces_)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ TEST_F(BicycleSteeringControllerTest, activate_success)
ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS);

// check that the message is reset
auto msg = controller_->input_ref_twist_.readFromNonRT();
EXPECT_TRUE(std::isnan((*msg)->twist.linear.x));
EXPECT_TRUE(std::isnan((*msg)->twist.linear.y));
EXPECT_TRUE(std::isnan((*msg)->twist.linear.z));
EXPECT_TRUE(std::isnan((*msg)->twist.angular.x));
EXPECT_TRUE(std::isnan((*msg)->twist.angular.y));
EXPECT_TRUE(std::isnan((*msg)->twist.angular.z));
auto msg = controller_->input_ref_twist_.get();
EXPECT_TRUE(std::isnan(msg.twist.linear.x));
EXPECT_TRUE(std::isnan(msg.twist.linear.y));
EXPECT_TRUE(std::isnan(msg.twist.linear.z));
EXPECT_TRUE(std::isnan(msg.twist.angular.x));
EXPECT_TRUE(std::isnan(msg.twist.angular.y));
EXPECT_TRUE(std::isnan(msg.twist.angular.z));
}

TEST_F(BicycleSteeringControllerTest, update_success)
Expand Down Expand Up @@ -147,11 +147,11 @@ TEST_F(BicycleSteeringControllerTest, test_update_logic)
ASSERT_FALSE(controller_->is_in_chained_mode());

// set command statically
std::shared_ptr<ControllerReferenceMsg> msg = std::make_shared<ControllerReferenceMsg>();
msg->header.stamp = controller_->get_node()->now();
msg->twist.linear.x = 0.1;
msg->twist.angular.z = 0.2;
controller_->input_ref_twist_.writeFromNonRT(msg);
ControllerReferenceMsg msg;
msg.header.stamp = controller_->get_node()->now();
msg.twist.linear.x = 0.1;
msg.twist.angular.z = 0.2;
controller_->input_ref_twist_.set(msg);

ASSERT_EQ(
controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)),
Expand All @@ -164,7 +164,7 @@ TEST_F(BicycleSteeringControllerTest, test_update_logic)
controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734,
COMMON_THRESHOLD);

EXPECT_FALSE(std::isnan((*(controller_->input_ref_twist_.readFromRT()))->twist.linear.x));
EXPECT_FALSE(std::isnan(controller_->input_ref_twist_.get().twist.linear.x));
EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size());
for (const auto & interface : controller_->reference_interfaces_)
{
Expand Down Expand Up @@ -197,7 +197,7 @@ TEST_F(BicycleSteeringControllerTest, test_update_logic_chained)
controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734,
COMMON_THRESHOLD);

EXPECT_TRUE(std::isnan((*(controller_->input_ref_twist_.readFromRT()))->twist.linear.x));
EXPECT_TRUE(std::isnan(controller_->input_ref_twist_.get().twist.linear.x));
EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size());
for (const auto & interface : controller_->reference_interfaces_)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ class SteeringControllersLibrary : public controller_interface::ChainableControl
rclcpp::Subscription<ControllerTwistReferenceMsg>::SharedPtr ref_subscriber_twist_ = nullptr;
rclcpp::Subscription<ControllerSteeringReferenceMsg>::SharedPtr ref_subscriber_steering_ =
nullptr;
realtime_tools::RealtimeBuffer<std::shared_ptr<ControllerTwistReferenceMsg>> input_ref_twist_;
realtime_tools::RealtimeBuffer<std::shared_ptr<ControllerSteeringReferenceMsg>>
input_ref_steering_;
// the RT Box containing the command messages
realtime_tools::RealtimeThreadSafeBox<ControllerTwistReferenceMsg> input_ref_twist_;
realtime_tools::RealtimeThreadSafeBox<ControllerSteeringReferenceMsg> input_ref_steering_;
// save the last references in case of unable to get value from box
ControllerTwistReferenceMsg current_ref_twist_;
ControllerSteeringReferenceMsg current_ref_steering_;
rclcpp::Duration ref_timeout_ = rclcpp::Duration::from_seconds(0.0); // 0ms

// Command subscribers and Controller State publisher
rclcpp::Subscription<ControllerTwistReferenceMsg>::SharedPtr ref_subscriber_twist_ = nullptr;
using ControllerStatePublisherOdom = realtime_tools::RealtimePublisher<ControllerStateMsgOdom>;
using ControllerStatePublisherTf = realtime_tools::RealtimePublisher<ControllerStateMsgTf>;

Expand Down
118 changes: 95 additions & 23 deletions steering_controllers_library/src/steering_controllers_library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ void reset_controller_reference_msg(
msg->steering_angle = std::numeric_limits<double>::quiet_NaN();
}

void reset_controller_reference_msg(
ControllerSteeringReferenceMsg & msg,
const std::shared_ptr<rclcpp_lifecycle::LifecycleNode> & node)
{
msg.header.stamp = node->now();
msg.linear_velocity = std::numeric_limits<double>::quiet_NaN();
msg.steering_angle = std::numeric_limits<double>::quiet_NaN();
}

} // namespace

namespace steering_controllers_library
Expand Down Expand Up @@ -271,21 +280,17 @@ controller_interface::CallbackReturn SteeringControllersLibrary::on_configure(
"~/reference", subscribers_qos,
std::bind(
&SteeringControllersLibrary::reference_callback_twist, this, std::placeholders::_1));
std::shared_ptr<ControllerTwistReferenceMsg> msg =
std::make_shared<ControllerTwistReferenceMsg>();
reset_controller_reference_msg(msg, get_node());
input_ref_twist_.writeFromNonRT(msg);
reset_controller_reference_msg(current_ref_twist_, get_node());
input_ref_twist_.set(current_ref_twist_);
}
else
{
ref_subscriber_steering_ = get_node()->create_subscription<ControllerSteeringReferenceMsg>(
"~/reference", subscribers_qos,
std::bind(
&SteeringControllersLibrary::reference_callback_steering, this, std::placeholders::_1));
std::shared_ptr<ControllerSteeringReferenceMsg> msg =
std::make_shared<ControllerSteeringReferenceMsg>();
reset_controller_reference_msg(msg, get_node());
input_ref_steering_.writeFromNonRT(msg);
reset_controller_reference_msg(current_ref_steering_, get_node());
input_ref_steering_.set(current_ref_steering_);
}

try
Expand Down Expand Up @@ -383,7 +388,7 @@ void SteeringControllersLibrary::reference_callback_twist(

if (ref_timeout_ == rclcpp::Duration::from_seconds(0) || age_of_last_command <= ref_timeout_)
{
input_ref_twist_.writeFromNonRT(msg);
input_ref_twist_.set(*msg);
}
else
{
Expand Down Expand Up @@ -411,7 +416,7 @@ void SteeringControllersLibrary::reference_callback_steering(

if (ref_timeout_ == rclcpp::Duration::from_seconds(0) || age_of_last_command <= ref_timeout_)
{
input_ref_steering_.writeFromNonRT(msg);
input_ref_steering_.set(*msg);
}
else
{
Expand Down Expand Up @@ -498,14 +503,17 @@ bool SteeringControllersLibrary::on_set_chained_mode(bool /*chained_mode*/) { re
controller_interface::CallbackReturn SteeringControllersLibrary::on_activate(
const rclcpp_lifecycle::State & /*previous_state*/)
{
// Set default value in command
// Try to set default value in command.
// If this fails, then another command will be received soon anyways.
if (params_.use_twist_input)
{
reset_controller_reference_msg(*(input_ref_twist_.readFromRT()), get_node());
reset_controller_reference_msg(current_ref_twist_, get_node());
input_ref_twist_.try_set(current_ref_twist_);
}
else
{
reset_controller_reference_msg(*(input_ref_steering_.readFromRT()), get_node());
reset_controller_reference_msg(current_ref_steering_, get_node());
input_ref_steering_.try_set(current_ref_steering_);
}

return controller_interface::CallbackReturn::SUCCESS;
Expand Down Expand Up @@ -533,20 +541,84 @@ controller_interface::return_type SteeringControllersLibrary::update_reference_f
{
if (params_.use_twist_input)
{
auto current_ref = *(input_ref_twist_.readFromRT());
if (!std::isnan(current_ref->twist.linear.x) && !std::isnan(current_ref->twist.angular.z))
auto current_ref_op = input_ref_twist_.try_get();
if (current_ref_op.has_value())
{
current_ref_twist_ = current_ref_op.value();
}

const auto age_of_last_command = time - current_ref_twist_.header.stamp;

// accept message only if there is no timeout
if (age_of_last_command <= ref_timeout_ || ref_timeout_ == rclcpp::Duration::from_seconds(0))
{
reference_interfaces_[0] = current_ref->twist.linear.x;
reference_interfaces_[1] = current_ref->twist.angular.z;
if (!std::isnan(current_ref_twist_.twist.linear.x) && !std::isnan(current_ref_twist_.twist.angular.z))
{
reference_interfaces_[0] = current_ref_twist_.twist.linear.x;
reference_interfaces_[1] = current_ref_twist_.twist.angular.z;

if (ref_timeout_ == rclcpp::Duration::from_seconds(0))
{
current_ref_twist_.twist.linear.x = std::numeric_limits<double>::quiet_NaN();
current_ref_twist_.twist.angular.z = std::numeric_limits<double>::quiet_NaN();

input_ref_twist_.try_set(current_ref_twist_);
}
}
}
else
{
if (!std::isnan(current_ref_twist_.twist.linear.x) && !std::isnan(current_ref_twist_.twist.angular.z))
{
reference_interfaces_[0] = std::numeric_limits<double>::quiet_NaN();
reference_interfaces_[1] = std::numeric_limits<double>::quiet_NaN();

current_ref_twist_.twist.linear.x = std::numeric_limits<double>::quiet_NaN();
current_ref_twist_.twist.angular.z = std::numeric_limits<double>::quiet_NaN();

input_ref_twist_.try_set(current_ref_twist_);
}
}
}
else
{
auto current_ref = *(input_ref_steering_.readFromRT());
if (!std::isnan(current_ref->linear_velocity) && !std::isnan(current_ref->steering_angle))
auto current_ref_op = input_ref_steering_.try_get();
if (current_ref_op.has_value())
{
current_ref_steering_ = current_ref_op.value();
}

const auto age_of_last_command = time - current_ref_steering_.header.stamp;

// accept message only if there is no timeout
if (age_of_last_command <= ref_timeout_ || ref_timeout_ == rclcpp::Duration::from_seconds(0))
{
reference_interfaces_[0] = current_ref->linear_velocity;
reference_interfaces_[1] = current_ref->steering_angle;
if (!std::isnan(current_ref_steering_.linear_velocity) && !std::isnan(current_ref_steering_.steering_angle))
{
reference_interfaces_[0] = current_ref_steering_.linear_velocity;
reference_interfaces_[1] = current_ref_steering_.steering_angle;

if (ref_timeout_ == rclcpp::Duration::from_seconds(0))
{
current_ref_steering_.linear_velocity = std::numeric_limits<double>::quiet_NaN();
current_ref_steering_.steering_angle = std::numeric_limits<double>::quiet_NaN();

input_ref_steering_.try_set(current_ref_steering_);
}
}
}
else
{
if (!std::isnan(current_ref_steering_.linear_velocity) && !std::isnan(current_ref_steering_.steering_angle))
{
reference_interfaces_[0] = std::numeric_limits<double>::quiet_NaN();
reference_interfaces_[1] = std::numeric_limits<double>::quiet_NaN();

current_ref_steering_.linear_velocity = std::numeric_limits<double>::quiet_NaN();
current_ref_steering_.steering_angle = std::numeric_limits<double>::quiet_NaN();

input_ref_steering_.try_set(current_ref_steering_);
}
}
}

Expand All @@ -567,8 +639,8 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c
if (!std::isnan(reference_interfaces_[0]) && !std::isnan(reference_interfaces_[1]))
{
const auto age_of_last_command = params_.use_twist_input
? time - (*(input_ref_twist_.readFromRT()))->header.stamp
: time - (*(input_ref_steering_.readFromRT()))->header.stamp;
? time - current_ref_twist_.header.stamp
: time - current_ref_steering_.header.stamp;

const auto timeout =
age_of_last_command > ref_timeout_ && ref_timeout_ != rclcpp::Duration::from_seconds(0);
Expand Down
3 changes: 1 addition & 2 deletions steering_controllers_library/src/steering_odometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,7 @@ bool SteeringOdometry::update_from_velocity(

double linear_velocity = get_linear_velocity_double_traction_axle(
right_traction_wheel_vel, left_traction_wheel_vel, steer_pos_);
const double angular_velocity =
convert_steering_angle_to_angular_velocity(linear_velocity, steer_pos_);
const double angular_velocity = std::tan(steer_pos_) * linear_velocity / wheel_base_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldnt it use convert_steering_angle_to_angular_velocity here?


return update_odometry(linear_velocity, angular_velocity, dt);
}
Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.