Skip to content

Commit d33e00b

Browse files
authored
[Transmissions] Add force interface (backport #2588) (#2678)
1 parent aba3cae commit d33e00b

File tree

5 files changed

+124
-5
lines changed

5 files changed

+124
-5
lines changed

doc/release_notes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,7 @@ ros2controlcli
214214
ros2 control <verb> <arguments> --ros-args -r __ns:=<namespace>
215215
216216
* The CLI verbs ``list_hardware_components`` and ``list_hardware_interfaces`` will now show the data type used by the internal Command and State interfaces (`#2204 <https://github.com/ros-controls/ros2_control/pull/2204>`_).
217+
218+
transmission_interface
219+
**********************
220+
* The ``simple_transmission`` and ``differential_transmission`` now also support the ``force`` interface (`#2588 <https://github.com/ros-controls/ros2_control/pull/2588>`_).

transmission_interface/include/transmission_interface/differential_transmission.hpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,14 @@ class DifferentialTransmission : public Transmission
168168
std::vector<JointHandle> joint_velocity_;
169169
std::vector<JointHandle> joint_effort_;
170170
std::vector<JointHandle> joint_torque_;
171+
std::vector<JointHandle> joint_force_;
171172
std::vector<JointHandle> joint_absolute_position_;
172173

173174
std::vector<ActuatorHandle> actuator_position_;
174175
std::vector<ActuatorHandle> actuator_velocity_;
175176
std::vector<ActuatorHandle> actuator_effort_;
176177
std::vector<ActuatorHandle> actuator_torque_;
178+
std::vector<ActuatorHandle> actuator_force_;
177179
std::vector<ActuatorHandle> actuator_absolute_position_;
178180
};
179181

@@ -236,12 +238,13 @@ void DifferentialTransmission::configure(
236238
get_ordered_handles(joint_handles, joint_names, hardware_interface::HW_IF_VELOCITY);
237239
joint_effort_ = get_ordered_handles(joint_handles, joint_names, hardware_interface::HW_IF_EFFORT);
238240
joint_torque_ = get_ordered_handles(joint_handles, joint_names, hardware_interface::HW_IF_TORQUE);
241+
joint_force_ = get_ordered_handles(joint_handles, joint_names, hardware_interface::HW_IF_FORCE);
239242
joint_absolute_position_ =
240243
get_ordered_handles(joint_handles, joint_names, HW_IF_ABSOLUTE_POSITION);
241244

242245
if (
243246
joint_position_.size() != 2 && joint_velocity_.size() != 2 && joint_effort_.size() != 2 &&
244-
joint_torque_.size() != 2 && joint_absolute_position_.size() != 2)
247+
joint_torque_.size() != 2 && joint_force_.size() != 2 && joint_absolute_position_.size() != 2)
245248
{
246249
throw Exception("Not enough valid or required joint handles were presented.");
247250
}
@@ -254,12 +257,14 @@ void DifferentialTransmission::configure(
254257
get_ordered_handles(actuator_handles, actuator_names, hardware_interface::HW_IF_EFFORT);
255258
actuator_torque_ =
256259
get_ordered_handles(actuator_handles, actuator_names, hardware_interface::HW_IF_TORQUE);
260+
actuator_force_ =
261+
get_ordered_handles(actuator_handles, actuator_names, hardware_interface::HW_IF_FORCE);
257262
actuator_absolute_position_ =
258263
get_ordered_handles(actuator_handles, actuator_names, HW_IF_ABSOLUTE_POSITION);
259264

260265
if (
261266
actuator_position_.size() != 2 && actuator_velocity_.size() != 2 &&
262-
actuator_effort_.size() != 2 && actuator_torque_.size() != 2 &&
267+
actuator_effort_.size() != 2 && actuator_torque_.size() != 2 && actuator_force_.size() != 2 &&
263268
actuator_absolute_position_.size() != 2)
264269
{
265270
throw Exception(
@@ -273,6 +278,7 @@ void DifferentialTransmission::configure(
273278
joint_velocity_.size() != actuator_velocity_.size() &&
274279
joint_effort_.size() != actuator_effort_.size() &&
275280
joint_torque_.size() != actuator_torque_.size() &&
281+
joint_force_.size() != actuator_force_.size() &&
276282
joint_absolute_position_.size() != actuator_absolute_position_.size())
277283
{
278284
throw Exception(
@@ -335,6 +341,18 @@ inline void DifferentialTransmission::actuator_to_joint()
335341
jr[1] * (act_tor[0].get_value() * ar[0] - act_tor[1].get_value() * ar[1]));
336342
}
337343

344+
auto & act_for = actuator_force_;
345+
auto & joint_for = joint_force_;
346+
if (act_for.size() == num_actuators() && joint_for.size() == num_joints())
347+
{
348+
assert(act_for[0] && act_for[1] && joint_for[0] && joint_for[1]);
349+
350+
joint_for[0].set_value(
351+
jr[0] * (act_for[0].get_value() * ar[0] + act_for[1].get_value() * ar[1]));
352+
joint_for[1].set_value(
353+
jr[1] * (act_for[0].get_value() * ar[0] - act_for[1].get_value() * ar[1]));
354+
}
355+
338356
auto & act_abs_pos = actuator_absolute_position_;
339357
auto & joint_abs_pos = joint_absolute_position_;
340358
if (act_abs_pos.size() == num_actuators() && joint_abs_pos.size() == num_joints())
@@ -404,6 +422,18 @@ inline void DifferentialTransmission::joint_to_actuator()
404422
act_tor[1].set_value(
405423
(joint_tor[0].get_value() / jr[0] - joint_tor[1].get_value() / jr[1]) / (2.0 * ar[1]));
406424
}
425+
426+
auto & act_for = actuator_force_;
427+
auto & joint_for = joint_force_;
428+
if (act_for.size() == num_actuators() && joint_for.size() == num_joints())
429+
{
430+
assert(act_for[0] && act_for[1] && joint_for[0] && joint_for[1]);
431+
432+
act_for[0].set_value(
433+
(joint_for[0].get_value() / jr[0] + joint_for[1].get_value() / jr[1]) / (2.0 * ar[0]));
434+
act_for[1].set_value(
435+
(joint_for[0].get_value() / jr[0] - joint_for[1].get_value() / jr[1]) / (2.0 * ar[1]));
436+
}
407437
}
408438

409439
std::string DifferentialTransmission::get_handles_info() const
@@ -415,11 +445,13 @@ std::string DifferentialTransmission::get_handles_info() const
415445
"Joint velocity: {}, Actuator velocity: {}\n"
416446
"Joint effort: {}, Actuator effort: {}\n"
417447
"Joint torque: {}, Actuator torque: {}\n"
448+
"Joint force: {}, Actuator force: {}\n"
418449
"Joint absolute position: {}, Actuator absolute position: {}"),
419450
to_string(get_names(joint_position_)), to_string(get_names(actuator_position_)),
420451
to_string(get_names(joint_velocity_)), to_string(get_names(actuator_velocity_)),
421452
to_string(get_names(joint_effort_)), to_string(get_names(actuator_effort_)),
422453
to_string(get_names(joint_torque_)), to_string(get_names(actuator_torque_)),
454+
to_string(get_names(joint_force_)), to_string(get_names(actuator_force_)),
423455
to_string(get_names(joint_absolute_position_)),
424456
to_string(get_names(actuator_absolute_position_)));
425457
}

transmission_interface/include/transmission_interface/simple_transmission.hpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,14 @@ class SimpleTransmission : public Transmission
135135
JointHandle joint_velocity_ = {"", "", nullptr};
136136
JointHandle joint_effort_ = {"", "", nullptr};
137137
JointHandle joint_torque_ = {"", "", nullptr};
138+
JointHandle joint_force_ = {"", "", nullptr};
138139
JointHandle joint_absolute_position_ = {"", "", nullptr};
139140

140141
ActuatorHandle actuator_position_ = {"", "", nullptr};
141142
ActuatorHandle actuator_velocity_ = {"", "", nullptr};
142143
ActuatorHandle actuator_effort_ = {"", "", nullptr};
143144
ActuatorHandle actuator_torque_ = {"", "", nullptr};
145+
ActuatorHandle actuator_force_ = {"", "", nullptr};
144146
ActuatorHandle actuator_absolute_position_ = {"", "", nullptr};
145147
};
146148

@@ -206,10 +208,11 @@ inline void SimpleTransmission::configure(
206208
joint_velocity_ = get_by_interface(joint_handles, hardware_interface::HW_IF_VELOCITY);
207209
joint_effort_ = get_by_interface(joint_handles, hardware_interface::HW_IF_EFFORT);
208210
joint_torque_ = get_by_interface(joint_handles, hardware_interface::HW_IF_TORQUE);
211+
joint_force_ = get_by_interface(joint_handles, hardware_interface::HW_IF_FORCE);
209212
joint_absolute_position_ = get_by_interface(joint_handles, HW_IF_ABSOLUTE_POSITION);
210213

211214
if (
212-
!joint_position_ && !joint_velocity_ && !joint_effort_ && !joint_torque_ &&
215+
!joint_position_ && !joint_velocity_ && !joint_effort_ && !joint_torque_ && !joint_force_ &&
213216
!joint_absolute_position_)
214217
{
215218
throw Exception("None of the provided joint handles are valid or from the required interfaces");
@@ -219,13 +222,15 @@ inline void SimpleTransmission::configure(
219222
actuator_velocity_ = get_by_interface(actuator_handles, hardware_interface::HW_IF_VELOCITY);
220223
actuator_effort_ = get_by_interface(actuator_handles, hardware_interface::HW_IF_EFFORT);
221224
actuator_torque_ = get_by_interface(actuator_handles, hardware_interface::HW_IF_TORQUE);
225+
actuator_force_ = get_by_interface(actuator_handles, hardware_interface::HW_IF_FORCE);
222226
actuator_absolute_position_ = get_by_interface(actuator_handles, HW_IF_ABSOLUTE_POSITION);
223227

224228
if (
225229
!actuator_position_ && !actuator_velocity_ && !actuator_effort_ && !actuator_torque_ &&
226-
!actuator_absolute_position_)
230+
!actuator_force_ && !actuator_absolute_position_)
227231
{
228-
throw Exception("None of the provided joint handles are valid or from the required interfaces");
232+
throw Exception(
233+
"None of the provided actuator handles are valid or from the required interfaces");
229234
}
230235
}
231236

@@ -251,6 +256,11 @@ inline void SimpleTransmission::actuator_to_joint()
251256
joint_torque_.set_value(actuator_torque_.get_value() * reduction_);
252257
}
253258

259+
if (joint_force_ && actuator_force_)
260+
{
261+
joint_force_.set_value(actuator_force_.get_value() * reduction_);
262+
}
263+
254264
if (joint_absolute_position_ && actuator_absolute_position_)
255265
{
256266
joint_absolute_position_.set_value(
@@ -279,6 +289,11 @@ inline void SimpleTransmission::joint_to_actuator()
279289
{
280290
actuator_torque_.set_value(joint_torque_.get_value() / reduction_);
281291
}
292+
293+
if (joint_force_ && actuator_force_)
294+
{
295+
actuator_force_.set_value(joint_force_.get_value() / reduction_);
296+
}
282297
}
283298

284299
} // namespace transmission_interface

transmission_interface/test/differential_transmission_test.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "transmission_interface/differential_transmission.hpp"
2222

2323
using hardware_interface::HW_IF_EFFORT;
24+
using hardware_interface::HW_IF_FORCE;
2425
using hardware_interface::HW_IF_POSITION;
2526
using hardware_interface::HW_IF_TORQUE;
2627
using hardware_interface::HW_IF_VELOCITY;
@@ -128,6 +129,7 @@ TEST(ConfigureTest, FailsWithBadHandles)
128129
testConfigureWithBadHandles(HW_IF_VELOCITY);
129130
testConfigureWithBadHandles(HW_IF_EFFORT);
130131
testConfigureWithBadHandles(HW_IF_TORQUE);
132+
testConfigureWithBadHandles(HW_IF_FORCE);
131133
testConfigureWithBadHandles(HW_IF_ABSOLUTE_POSITION);
132134
}
133135

@@ -225,6 +227,7 @@ TEST_F(BlackBoxTest, IdentityMap)
225227
testIdentityMap(transmission, input_value, HW_IF_VELOCITY);
226228
testIdentityMap(transmission, input_value, HW_IF_EFFORT);
227229
testIdentityMap(transmission, input_value, HW_IF_TORQUE);
230+
testIdentityMap(transmission, input_value, HW_IF_FORCE);
228231
}
229232
}
230233
}
@@ -293,6 +296,18 @@ TEST_F(WhiteBoxTest, DontMoveJoints)
293296
EXPECT_THAT(0.0, DoubleNear(j_val[1], EPS));
294297
}
295298

299+
// Force interface
300+
{
301+
auto a1_handle = ActuatorHandle("act1", HW_IF_FORCE, a_vec[0]);
302+
auto a2_handle = ActuatorHandle("act2", HW_IF_FORCE, a_vec[1]);
303+
auto joint1_handle = JointHandle("joint1", HW_IF_FORCE, j_vec[0]);
304+
auto joint2_handle = JointHandle("joint2", HW_IF_FORCE, j_vec[1]);
305+
trans.configure({joint1_handle, joint2_handle}, {a1_handle, a2_handle});
306+
trans.actuator_to_joint();
307+
EXPECT_THAT(0.0, DoubleNear(j_val[0], EPS));
308+
EXPECT_THAT(0.0, DoubleNear(j_val[1], EPS));
309+
}
310+
296311
// Absolute position interface
297312
{
298313
auto a1_handle = ActuatorHandle("act1", HW_IF_ABSOLUTE_POSITION, a_vec[0]);
@@ -365,6 +380,18 @@ TEST_F(WhiteBoxTest, MoveFirstJointOnly)
365380
EXPECT_THAT(0.0, DoubleNear(j_val[1], EPS));
366381
}
367382

383+
// Force interface
384+
{
385+
auto a1_handle = ActuatorHandle("act1", HW_IF_FORCE, a_vec[0]);
386+
auto a2_handle = ActuatorHandle("act2", HW_IF_FORCE, a_vec[1]);
387+
auto joint1_handle = JointHandle("joint1", HW_IF_FORCE, j_vec[0]);
388+
auto joint2_handle = JointHandle("joint2", HW_IF_FORCE, j_vec[1]);
389+
trans.configure({joint1_handle, joint2_handle}, {a1_handle, a2_handle});
390+
trans.actuator_to_joint();
391+
EXPECT_THAT(400.0, DoubleNear(j_val[0], EPS));
392+
EXPECT_THAT(0.0, DoubleNear(j_val[1], EPS));
393+
}
394+
368395
// Absolute position interface
369396
{
370397
auto a1_handle = ActuatorHandle("act1", HW_IF_ABSOLUTE_POSITION, a_vec[0]);
@@ -437,6 +464,18 @@ TEST_F(WhiteBoxTest, MoveSecondJointOnly)
437464
EXPECT_THAT(400.0, DoubleNear(j_val[1], EPS));
438465
}
439466

467+
// Force interface
468+
{
469+
auto a1_handle = ActuatorHandle("act1", HW_IF_FORCE, a_vec[0]);
470+
auto a2_handle = ActuatorHandle("act2", HW_IF_FORCE, a_vec[1]);
471+
auto joint1_handle = JointHandle("joint1", HW_IF_FORCE, j_vec[0]);
472+
auto joint2_handle = JointHandle("joint2", HW_IF_FORCE, j_vec[1]);
473+
trans.configure({joint1_handle, joint2_handle}, {a1_handle, a2_handle});
474+
trans.actuator_to_joint();
475+
EXPECT_THAT(0.0, DoubleNear(j_val[0], EPS));
476+
EXPECT_THAT(400.0, DoubleNear(j_val[1], EPS));
477+
}
478+
440479
// Absolute position interface
441480
{
442481
auto a1_handle = ActuatorHandle("act1", HW_IF_ABSOLUTE_POSITION, a_vec[0]);
@@ -514,6 +553,18 @@ TEST_F(WhiteBoxTest, MoveBothJoints)
514553
EXPECT_THAT(520.0, DoubleNear(j_val[1], EPS));
515554
}
516555

556+
// Force interface
557+
{
558+
auto a1_handle = ActuatorHandle("act1", HW_IF_FORCE, a_vec[0]);
559+
auto a2_handle = ActuatorHandle("act2", HW_IF_FORCE, a_vec[1]);
560+
auto joint1_handle = JointHandle("joint1", HW_IF_FORCE, j_vec[0]);
561+
auto joint2_handle = JointHandle("joint2", HW_IF_FORCE, j_vec[1]);
562+
trans.configure({joint1_handle, joint2_handle}, {a1_handle, a2_handle});
563+
trans.actuator_to_joint();
564+
EXPECT_THAT(140.0, DoubleNear(j_val[0], EPS));
565+
EXPECT_THAT(520.0, DoubleNear(j_val[1], EPS));
566+
}
567+
517568
// Absolute position interface
518569
{
519570
auto a1_handle = ActuatorHandle("act1", HW_IF_ABSOLUTE_POSITION, a_vec[0]);

transmission_interface/test/simple_transmission_test.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "transmission_interface/simple_transmission.hpp"
2020

2121
using hardware_interface::HW_IF_EFFORT;
22+
using hardware_interface::HW_IF_FORCE;
2223
using hardware_interface::HW_IF_POSITION;
2324
using hardware_interface::HW_IF_TORQUE;
2425
using hardware_interface::HW_IF_VELOCITY;
@@ -164,6 +165,12 @@ TEST_P(BlackBoxTest, IdentityMap)
164165
reset_values();
165166
testIdentityMap(trans, HW_IF_TORQUE, -1.0);
166167

168+
testIdentityMap(trans, HW_IF_FORCE, 1.0);
169+
reset_values();
170+
testIdentityMap(trans, HW_IF_FORCE, 0.0);
171+
reset_values();
172+
testIdentityMap(trans, HW_IF_FORCE, -1.0);
173+
167174
testIdentityMap(trans, HW_IF_ABSOLUTE_POSITION, 1.0);
168175
reset_values();
169176
testIdentityMap(trans, HW_IF_ABSOLUTE_POSITION, 0.0);
@@ -232,6 +239,16 @@ TEST_F(WhiteBoxTest, MoveJoint)
232239
EXPECT_THAT(10.0, DoubleNear(j_val, EPS));
233240
}
234241

242+
// Force interface
243+
{
244+
auto actuator_handle = ActuatorHandle("act1", HW_IF_FORCE, &a_val);
245+
auto joint_handle = JointHandle("joint1", HW_IF_FORCE, &j_val);
246+
trans.configure({joint_handle}, {actuator_handle});
247+
248+
trans.actuator_to_joint();
249+
EXPECT_THAT(10.0, DoubleNear(j_val, EPS));
250+
}
251+
235252
// Absolute position interface
236253
{
237254
auto actuator_handle = ActuatorHandle("act1", HW_IF_ABSOLUTE_POSITION, &a_val);

0 commit comments

Comments
 (0)