Skip to content

Commit e163a69

Browse files
committed
Rename to SyncGroupVelocityToPositionController and rework sync semantics
Rename the controller to better reflect its current scope (group actions, synchronization, trapezoidal braking) beyond the original vel→pos role: - Class: VelocityToPositionCommandController -> SyncGroupVelocityToPositionController - Plugin type: velocity_to_position_command_controller/* -> sync_group_velocity_to_position_controller/* - Source/header/test/param files renamed to match - Plugin description rewritten to cover the broader feature set Sync logic reworked from live offset tracking to edge-triggered capture: on the false->true transition of a group's sync state, snapshot the relative pair offset and freeze it for the duration of synced motion. Eliminates extra movement caused by FP equality flicker on chained inputs and by partner-brake transients polluting the live offset. Sync now also requires a non-zero common command, so two stopped joints no longer trivially register as synced. Fix segfault in publish_debug_joint_state_in: publishers were created in on_init() before joints_ was populated, leaving msg_.velocity sized zero. Move the initial update_debug_publishers() call to on_configure(), after read_parameters(). Drop spammy per-tick INFO logs ([BRAKE] transitions, group-action completion). Add structured comments to the params YAML grouping parameters by purpose.
1 parent c9915a9 commit e163a69

15 files changed

Lines changed: 272 additions & 230 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ Acts as a motion gatekeeper in real-time.
6464
Converts **velocity references** into **position commands** for joint hardware. Useful when an upstream controller outputs velocity commands but the hardware only accepts position commands.
6565

6666
> **Important:** This controller does **not** perform self-collision checking. It should be chained downstream of the **Safety Position Controller** (see section 4) to ensure collision avoidance and joint limit enforcement. A typical chain is:
67-
> `upstream velocity source → vel_to_pos_controller → safety_position_controller → hardware`
67+
> `upstream velocity source → flipper_velocity_to_position_controller → safety_position_controller → hardware`
6868
6969
### Features
7070

dynamics_mock_hardware/config/controller_spawner.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
controllers:
1111
- joint_state_broadcaster
12-
- vel_to_pos_controller
12+
- flipper_velocity_to_position_controller
1313
- flipper_velocity_controller
1414
- arm_trajectory_controller
1515
- gripper_trajectory_controller
@@ -20,7 +20,7 @@
2020
flipper_velocity_controller:
2121
activate: true
2222

23-
vel_to_pos_controller:
23+
flipper_velocity_to_position_controller:
2424
activate: true
2525

2626
arm_trajectory_controller:

dynamics_mock_hardware/config/controllers.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Controller configuration for dynamics_mock_hardware simulation.
22
# Simplified chain: no safety_position_controllers (need SRDF/MoveIt).
3-
# Flipper chain: flipper_velocity_controller -> vel_to_pos_controller -> hardware
3+
# Flipper chain: flipper_velocity_controller -> flipper_velocity_to_position_controller -> hardware
44
# Arm chain: arm_trajectory_controller -> hardware
55
/**:
66
controller_manager:
@@ -17,8 +17,8 @@
1717
flipper_trajectory_controller:
1818
type: joint_trajectory_controller/JointTrajectoryController
1919

20-
vel_to_pos_controller:
21-
type: velocity_to_position_command_controller/VelocityToPositionCommandController
20+
flipper_velocity_to_position_controller:
21+
type: sync_group_velocity_to_position_controller/SyncGroupVelocityToPositionController
2222

2323
# --------- Arm Controllers ------------
2424
arm_trajectory_controller:
@@ -37,12 +37,12 @@
3737
- flipper_bl_joint
3838
- flipper_br_joint
3939

40-
passthrough_controller: vel_to_pos_controller
40+
passthrough_controller: flipper_velocity_to_position_controller
4141
interface_type: velocity
4242
safety_timer_duration: 10000 # effectively disabled for simulation
4343

4444
# ---------- Velocity to position controller ----------
45-
vel_to_pos_controller:
45+
flipper_velocity_to_position_controller:
4646
ros__parameters:
4747
joints:
4848
- flipper_fl_joint

hector_ros_controllers/CMakeLists.txt

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ set(DEFS PINOCCHIO_WITH_HPP_FCL PINOCCHIO_URDFDOM_TYPEDEF_SHARED_PTR
4646
# Add parameter_libraries here
4747

4848
generate_parameter_library(
49-
velocity_to_position_command_controller_parameters
50-
params/velocity_to_position_command_controller_parameters.yaml)
49+
sync_group_velocity_to_position_controller_parameters
50+
params/sync_group_velocity_to_position_controller_parameters.yaml)
5151

5252
generate_parameter_library(
5353
self_collision_avoidance_controller_parameters
@@ -63,8 +63,8 @@ generate_parameter_library(safety_position_controller_parameters
6363
add_library(
6464
controllers SHARED
6565
src/safety_forward_controller.cpp
66-
src/velocity_to_position_command_controller.cpp
67-
src/velocity_to_position_command_controller_actions.cpp
66+
src/sync_group_velocity_to_position_controller.cpp
67+
src/sync_group_velocity_to_position_controller_actions.cpp
6868
src/self_collision_avoidance_controller.cpp
6969
src/safety_position_controller.cpp
7070
src/collision_checker.cpp)
@@ -80,7 +80,7 @@ target_link_libraries(
8080
PUBLIC fcl
8181
hpp-fcl::hpp-fcl
8282
pinocchio::pinocchio
83-
velocity_to_position_command_controller_parameters
83+
sync_group_velocity_to_position_controller_parameters
8484
self_collision_avoidance_controller_parameters
8585
safety_forward_controller_parameters
8686
safety_position_controller_parameters)
@@ -96,7 +96,7 @@ pluginlib_export_plugin_description_file(controller_interface
9696
install(DIRECTORY include/ DESTINATION include/)
9797
install(
9898
TARGETS controllers
99-
velocity_to_position_command_controller_parameters
99+
sync_group_velocity_to_position_controller_parameters
100100
self_collision_avoidance_controller_parameters
101101
safety_forward_controller_parameters
102102
safety_position_controller_parameters
@@ -138,7 +138,7 @@ if(BUILD_TESTING)
138138
hpp-fcl::hpp-fcl
139139
pinocchio::pinocchio
140140
ad_kinematics::ad_kinematics
141-
velocity_to_position_command_controller_parameters
141+
sync_group_velocity_to_position_controller_parameters
142142
self_collision_avoidance_controller_parameters
143143
safety_forward_controller_parameters
144144
safety_position_controller_parameters)
@@ -163,27 +163,28 @@ if(BUILD_TESTING)
163163
ament_index_cpp::ament_index_cpp)
164164
target_compile_definitions(test_safety_position_controller PRIVATE ${DEFS})
165165

166-
ament_add_gmock(test_velocity_to_position_command_controller
167-
test/test_velocity_to_position_command_controller.cpp)
166+
ament_add_gmock(test_sync_group_velocity_to_position_controller
167+
test/test_sync_group_velocity_to_position_controller.cpp)
168168
target_include_directories(
169-
test_velocity_to_position_command_controller
169+
test_sync_group_velocity_to_position_controller
170170
PRIVATE ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/test)
171171
target_link_libraries(
172-
test_velocity_to_position_command_controller
172+
test_sync_group_velocity_to_position_controller
173173
${PROJECT_NAME}::controllers_test_doubles ament_index_cpp::ament_index_cpp)
174-
target_compile_definitions(test_velocity_to_position_command_controller
174+
target_compile_definitions(test_sync_group_velocity_to_position_controller
175175
PRIVATE ${DEFS})
176176

177-
ament_add_gmock(test_velocity_to_position_command_controller_actions
178-
test/test_velocity_to_position_command_controller_actions.cpp)
177+
ament_add_gmock(
178+
test_sync_group_velocity_to_position_controller_actions
179+
test/test_sync_group_velocity_to_position_controller_actions.cpp)
179180
target_include_directories(
180-
test_velocity_to_position_command_controller_actions
181+
test_sync_group_velocity_to_position_controller_actions
181182
PRIVATE ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/test)
182183
target_link_libraries(
183-
test_velocity_to_position_command_controller_actions
184+
test_sync_group_velocity_to_position_controller_actions
184185
${PROJECT_NAME}::controllers_test_doubles ament_index_cpp::ament_index_cpp)
185186
target_compile_definitions(
186-
test_velocity_to_position_command_controller_actions PRIVATE ${DEFS})
187+
test_sync_group_velocity_to_position_controller_actions PRIVATE ${DEFS})
187188
endif()
188189

189190
ament_package()

hector_ros_controllers/hector_ros_controller_plugin.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<library path="libcontrollers">
3-
<class name="velocity_to_position_command_controller/VelocityToPositionCommandController" type="velocity_to_position_command_controller::VelocityToPositionCommandController" base_class_type="controller_interface::ChainableControllerInterface">
3+
<class name="sync_group_velocity_to_position_controller/SyncGroupVelocityToPositionController" type="sync_group_velocity_to_position_controller::SyncGroupVelocityToPositionController" base_class_type="controller_interface::ChainableControllerInterface">
44
<description>
5-
The velocity to position command controller provides a velocity input and converts it to position commands.
5+
Converts per-joint velocity references into position commands, with trapezoidal braking,
6+
optional pairwise group synchronization, and per-group action interfaces for drive-to-target
7+
and sync-to-position motions.
68
</description>
79
</class>
810
<class name="self_collision_avoidance_controller/SelfCollisionAvoidanceController" type="self_collision_avoidance_controller::SelfCollisionAvoidanceController" base_class_type="controller_interface::ChainableControllerInterface">

hector_ros_controllers/include/velocity_to_position_command_controller/velocity_to_position_command_controller.hpp renamed to hector_ros_controllers/include/sync_group_velocity_to_position_controller/sync_group_velocity_to_position_controller.hpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef VELOCITY_TO_POSITION_COMMAND_CONTROLLER__VELOCITY_TO_POSITION_COMMAND_CONTROLLER_HPP_
2-
#define VELOCITY_TO_POSITION_COMMAND_CONTROLLER__VELOCITY_TO_POSITION_COMMAND_CONTROLLER_HPP_
1+
#ifndef SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER__SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER_HPP_
2+
#define SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER__SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER_HPP_
33

44
#include <atomic>
55
#include <functional>
@@ -21,18 +21,18 @@
2121
#include "sensor_msgs/msg/joint_state.hpp"
2222
#include "std_msgs/msg/bool.hpp"
2323
#include "std_msgs/msg/float64_multi_array.hpp"
24+
#include "sync_group_velocity_to_position_controller/sync_pair_manager.hpp"
2425
#include "urdf_parser/urdf_parser.h"
25-
#include "velocity_to_position_command_controller/sync_pair_manager.hpp"
2626

27-
#include "velocity_to_position_command_controller/trapezoidal_profile.hpp"
27+
#include "sync_group_velocity_to_position_controller/trapezoidal_profile.hpp"
2828

2929
// auto-generated by generate_parameter_library
30-
#include <hector_ros_controllers/velocity_to_position_command_controller_parameters.hpp>
30+
#include <hector_ros_controllers/sync_group_velocity_to_position_controller_parameters.hpp>
3131

3232
#include <hector_ros_controllers_msgs/action/drive_flipper_group.hpp>
3333
#include <hector_ros_controllers_msgs/action/sync_flipper_group.hpp>
3434

35-
namespace velocity_to_position_command_controller
35+
namespace sync_group_velocity_to_position_controller
3636
{
3737
using CmdType = std_msgs::msg::Float64MultiArray;
3838
using DriveFlipperGroupAction = hector_ros_controllers_msgs::action::DriveFlipperGroup;
@@ -71,12 +71,12 @@ struct GroupActionCommand {
7171
* Subscribes to:
7272
* - \b commands (std_msgs::msg::Float64MultiArray) : The velocity commands to apply.
7373
*/
74-
class VelocityToPositionCommandController : public controller_interface::ChainableControllerInterface
74+
class SyncGroupVelocityToPositionController : public controller_interface::ChainableControllerInterface
7575
{
7676
public:
77-
VelocityToPositionCommandController();
77+
SyncGroupVelocityToPositionController();
7878

79-
~VelocityToPositionCommandController() override = default;
79+
~SyncGroupVelocityToPositionController() override = default;
8080

8181
controller_interface::InterfaceConfiguration command_interface_configuration() const override;
8282

@@ -121,7 +121,6 @@ class VelocityToPositionCommandController : public controller_interface::Chainab
121121

122122
// Synchronization
123123
void update_sync_states( const std::vector<double> &vel_commands );
124-
void update_sync_offsets();
125124
void reset_sync_offsets( size_t joint_idx );
126125
double sync_pd_control( size_t joint_idx, double vel_command );
127126

@@ -283,6 +282,6 @@ class VelocityToPositionCommandController : public controller_interface::Chainab
283282
void cleanup_monitor_threads(); ///< Join+erase all threads (used on deactivate).
284283
};
285284

286-
} // namespace velocity_to_position_command_controller
285+
} // namespace sync_group_velocity_to_position_controller
287286

288-
#endif // VELOCITY_TO_POSITION_COMMAND_CONTROLLER__VELOCITY_TO_POSITION_COMMAND_CONTROLLER_HPP_
287+
#endif // SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER__SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER_HPP_

hector_ros_controllers/include/velocity_to_position_command_controller/sync_pair_manager.hpp renamed to hector_ros_controllers/include/sync_group_velocity_to_position_controller/sync_pair_manager.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
#ifndef VELOCITY_TO_POSITION_COMMAND_CONTROLLER__SYNC_PAIR_MANAGER_HPP_
2-
#define VELOCITY_TO_POSITION_COMMAND_CONTROLLER__SYNC_PAIR_MANAGER_HPP_
1+
#ifndef SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER__SYNC_PAIR_MANAGER_HPP_
2+
#define SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER__SYNC_PAIR_MANAGER_HPP_
33

44
#include <cmath>
55
#include <limits>
66
#include <string>
77
#include <unordered_map>
88
#include <vector>
99

10-
namespace velocity_to_position_command_controller
10+
namespace sync_group_velocity_to_position_controller
1111
{
1212

1313
/**
@@ -111,6 +111,6 @@ class SyncPairManager
111111
std::vector<double> pair_offsets_;
112112
};
113113

114-
} // namespace velocity_to_position_command_controller
114+
} // namespace sync_group_velocity_to_position_controller
115115

116-
#endif // VELOCITY_TO_POSITION_COMMAND_CONTROLLER__SYNC_PAIR_MANAGER_HPP_
116+
#endif // SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER__SYNC_PAIR_MANAGER_HPP_

hector_ros_controllers/include/velocity_to_position_command_controller/trapezoidal_profile.hpp renamed to hector_ros_controllers/include/sync_group_velocity_to_position_controller/trapezoidal_profile.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
#ifndef VELOCITY_TO_POSITION_COMMAND_CONTROLLER__TRAPEZOIDAL_PROFILE_HPP_
2-
#define VELOCITY_TO_POSITION_COMMAND_CONTROLLER__TRAPEZOIDAL_PROFILE_HPP_
1+
#ifndef SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER__TRAPEZOIDAL_PROFILE_HPP_
2+
#define SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER__TRAPEZOIDAL_PROFILE_HPP_
33

44
#include <cmath>
55
#include <utility>
66

7-
namespace velocity_to_position_command_controller
7+
namespace sync_group_velocity_to_position_controller
88
{
99

1010
/// RT-safe trapezoidal velocity profile (pure math, no allocations).
@@ -135,6 +135,6 @@ struct TrapezoidalProfile {
135135
}
136136
};
137137

138-
} // namespace velocity_to_position_command_controller
138+
} // namespace sync_group_velocity_to_position_controller
139139

140-
#endif // VELOCITY_TO_POSITION_COMMAND_CONTROLLER__TRAPEZOIDAL_PROFILE_HPP_
140+
#endif // SYNC_GROUP_VELOCITY_TO_POSITION_CONTROLLER__TRAPEZOIDAL_PROFILE_HPP_
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
sync_group_velocity_to_position_controller:
2+
# --- Joint topology -------------------------------------------------------
3+
joints: {type: string_array, default_value: [], description: Name of the joints to control}
4+
5+
# Per-joint group label (must be empty or have exactly one entry per joint).
6+
# Joints sharing a label form a synchronous group; pairs in the same group
7+
# hold their relative offset while receiving identical velocity commands.
8+
synchronous_groups: {type: string_array, default_value: [], description: Per-joint group label for pairwise synchronization}
9+
10+
# Optional upstream chain controller. If set, command interfaces are claimed
11+
# as "<passthrough_controller>/<joint>/position" instead of "<joint>/position".
12+
passthrough_controller: {type: string, default_value: '', description: Name of passthrough controller exposing the position command interfaces}
13+
14+
# --- Safety ---------------------------------------------------------------
15+
# Hard e-stop subscription. While true, all joints freeze in place.
16+
e_stop_topic: {type: string, default_value: estop_board/hard_estop, description: Topic for hard e-stop (std_msgs/Bool). When true all joints are stopped.}
17+
18+
# Zero reference interfaces if no non-zero command is received for this many
19+
# seconds. 0 disables (rely on upstream SafetyForwardController instead).
20+
velocity_command_timeout: {type: double, default_value: 0.0, description: Auto-zero references if no non-zero command for N seconds (0 = disabled)}
21+
22+
# --- Per-joint PD (velocity tracking) -------------------------------------
23+
# The control law integrates the velocity reference into a target position
24+
# and adds a PD term on velocity error. kp scales (vel_cmd - vel_state);
25+
# kd damps current velocity. Both terms are scaled by dt internally.
26+
kp: {type: double, default_value: 1.0, description: P gain on velocity error (vel_cmd - vel_state)}
27+
kd: {type: double, default_value: 0.1, description: D gain damping current velocity}
28+
29+
# --- Pair synchronization -------------------------------------------------
30+
# When two joints in the same group receive identical non-zero velocity
31+
# commands, their relative offset at that instant is captured and a PD
32+
# correction pulls them back toward that offset. Offset is frozen until
33+
# commands diverge again.
34+
kp_sync: {type: double, default_value: 1.0, description: P gain on pair offset error}
35+
kd_sync: {type: double, default_value: 0.1, description: D gain on pair velocity difference}
36+
37+
# Sync correction is clamped to max(|vel_cmd| * factor, min_threshold) rad/s.
38+
# The factor lets correction grow with commanded speed; the min_threshold
39+
# ensures non-zero correction at low speeds (set 0 to disable that floor).
40+
sync_velocity_factor: {type: double, default_value: 1.0, description: Sync correction cap as a fraction of commanded velocity}
41+
sync_velocity_min_threshold: {type: double, default_value: 0.1, description: Minimum sync correction cap in rad/s (floor for the factor-based cap)}
42+
43+
# --- Motion limits --------------------------------------------------------
44+
# Velocity references are clamped to [-max_velocity, max_velocity].
45+
# Acceleration / deceleration shape the trapezoidal profiles used for the
46+
# action interfaces (drive/sync) and for stopping when vel_cmd hits zero.
47+
# Deceleration is typically larger than acceleration for snappier stops.
48+
max_velocity: {type: double, default_value: 1.0, description: Velocity clamp (rad/s) and cruise speed for action profiles}
49+
max_acceleration: {type: double, default_value: 2.0, description: Trapezoidal accel for drive/sync action profiles (rad/s^2)}
50+
max_deceleration: {type: double, default_value: 4.0, description: Trapezoidal decel for braking on vel_cmd -> 0 (rad/s^2)}
51+
52+
# --- Misc ----------------------------------------------------------------
53+
# Below this measured velocity a joint is treated as "at rest" for state
54+
# transitions out of STOPPING. Mostly affects edge cases at very low speeds.
55+
stopping_velocity_threshold: {type: double, default_value: 0.005, description: abs(vel_state) below which a joint is considered stopped}
56+
57+
# If true, publishes ~/debug_in_joint_states, ~/debug_out_joint_states,
58+
# and ~/sync_status for tuning. Off by default to avoid extra traffic.
59+
publish_debug_joint_states: {type: bool, default_value: false, description: Enable RT debug publishers (in/out joint states + sync status)}
60+
61+
# Default target for the upright group action (used when the action goal
62+
# leaves target_position unset).
63+
upright_position: {type: double, default_value: 1.517, description: Default upright-action target position in radians}

hector_ros_controllers/params/velocity_to_position_command_controller_parameters.yaml

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)