Skip to content

Commit 708df74

Browse files
authored
Fix admittance position state updates (#2514)
1 parent 0c7603e commit 708df74

3 files changed

Lines changed: 62 additions & 9 deletions

File tree

admittance_controller/include/admittance_controller/admittance_rule.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct AdmittanceState
3838
{
3939
admittance_velocity.setZero();
4040
admittance_acceleration.setZero();
41+
admittance_position.setIdentity();
4142
damping.setZero();
4243
mass.setOnes();
4344
mass_inv.setZero();

admittance_controller/include/admittance_controller/admittance_rule_impl.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@ bool AdmittanceRule::calculate_admittance_rule(AdmittanceState & admittance_stat
255255
auto R_ref = admittance_state.ref_trans_base_ft.rotation();
256256
auto R_desired = desired_trans_base_ft.rotation();
257257
auto R = R_desired * R_ref.transpose();
258+
259+
admittance_state.admittance_position.setIdentity();
260+
admittance_state.admittance_position.translation() = X.head<3>();
261+
admittance_state.admittance_position.linear() = R;
262+
258263
auto angle_axis = Eigen::AngleAxisd(R);
259264
X.block<3, 1>(3, 0) = angle_axis.angle() * angle_axis.axis();
260265

admittance_controller/test/test_admittance_rule_impl.cpp

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -166,16 +166,19 @@ class MassMatrixTransformationTest : public ::testing::Test
166166
}
167167

168168
protected:
169-
// Configure mock kinematics to use identity transformations
170-
// This isolates mass matrix transformation logic from actual robot kinematics
171-
void setupMockKinematics()
169+
// Configure mock kinematics with a deterministic link transform.
170+
void setupMockKinematics(const Eigen::Isometry3d & link_transform = Eigen::Isometry3d::Identity())
172171
{
173-
// All transforms are identity - no rotation or translation
174172
EXPECT_CALL(
175173
*mock_kinematics_ptr_, calculate_link_transform(::testing::_, ::testing::_, ::testing::_))
176174
.WillRepeatedly(
177-
::testing::DoAll(
178-
::testing::SetArgReferee<2>(Eigen::Isometry3d::Identity()), ::testing::Return(true)));
175+
::testing::Invoke(
176+
[link_transform](
177+
const Eigen::VectorXd &, const std::string &, Eigen::Isometry3d & transform) -> bool
178+
{
179+
transform = link_transform;
180+
return true;
181+
}));
179182

180183
// Use identity Jacobian: cartesian deltas = joint deltas
181184
// This allows mass matrix effects to propagate directly to joint space
@@ -278,7 +281,7 @@ class MassMatrixTransformationTest : public ::testing::Test
278281
MockKinematicsInterface * mock_kinematics_ptr_;
279282
};
280283

281-
// Test 1: Verify that calculate_admittance_rule succeeds with rotated control frame
284+
// Verify that calculate_admittance_rule succeeds with rotated control frame
282285
// and produces motion when force is applied
283286
// cppcheck-suppress syntaxError
284287
// To suppress the warning reported by cppcheck for complex macro expansion
@@ -309,7 +312,51 @@ TEST_F(MassMatrixTransformationTest, mass_matrix_transformation_consistency)
309312
EXPECT_GT(state.joint_pos.norm(), 0.0) << "Should produce motion when force is applied";
310313
}
311314

312-
// Test 2: Verify that higher mass in control frame results in less motion
315+
TEST(AdmittanceStateTest, initializes_admittance_position_to_identity)
316+
{
317+
const AdmittanceState state(6);
318+
319+
EXPECT_TRUE(state.admittance_position.matrix().isApprox(Eigen::Isometry3d::Identity().matrix()));
320+
}
321+
322+
TEST_F(MassMatrixTransformationTest, updates_admittance_position_from_relative_transform)
323+
{
324+
Eigen::Isometry3d reference_transform = Eigen::Isometry3d::Identity();
325+
reference_transform.translation() = Eigen::Vector3d(-0.4, 0.5, 0.2);
326+
reference_transform.linear() =
327+
Eigen::AngleAxisd(-M_PI / 6.0, Eigen::Vector3d::UnitY()).toRotationMatrix();
328+
329+
Eigen::Isometry3d desired_transform = Eigen::Isometry3d::Identity();
330+
desired_transform.translation() = Eigen::Vector3d(0.1, -0.2, 0.3);
331+
desired_transform.linear() =
332+
Eigen::AngleAxisd(M_PI / 4.0, Eigen::Vector3d::UnitZ()).toRotationMatrix();
333+
334+
Eigen::Isometry3d expected_relative_transform = Eigen::Isometry3d::Identity();
335+
expected_relative_transform.translation() =
336+
desired_transform.translation() - reference_transform.translation();
337+
expected_relative_transform.linear() =
338+
desired_transform.rotation() * reference_transform.rotation().transpose();
339+
340+
const Vector6d mass = Vector6d::Ones();
341+
const Vector6d stiffness = Vector6d::Zero();
342+
const Vector6d damping = Vector6d::Zero();
343+
const Vector6d wrench = Vector6d::Zero();
344+
345+
AdmittanceState state =
346+
createAdmittanceState(Eigen::Matrix3d::Identity(), mass, stiffness, damping, wrench);
347+
state.ref_trans_base_ft = reference_transform;
348+
349+
// Use a sentinel to verify that calculate_admittance_rule updates the field.
350+
state.admittance_position = Eigen::Isometry3d::Identity();
351+
state.admittance_position.translation() = Eigen::Vector3d(1.0, 2.0, 3.0);
352+
353+
setupMockKinematics(desired_transform);
354+
355+
ASSERT_TRUE(admittance_rule_->calculate_admittance_rule(state, DEFAULT_DT));
356+
EXPECT_TRUE(state.admittance_position.matrix().isApprox(expected_relative_transform.matrix()));
357+
}
358+
359+
// Verify that higher mass in control frame results in less motion
313360
// Physics expectation: F = ma, so higher mass -> lower acceleration -> less motion
314361
TEST_F(MassMatrixTransformationTest, mass_affects_motion_in_rotated_frame)
315362
{
@@ -352,7 +399,7 @@ TEST_F(MassMatrixTransformationTest, mass_affects_motion_in_rotated_frame)
352399
EXPECT_GT(motion_low, motion_high) << "Higher mass should result in smaller motion (F=ma)";
353400
}
354401

355-
// Test 3: Verify mass matrix transformation from control frame to base frame
402+
// Verify mass matrix transformation from control frame to base frame
356403
// Test scenario: With control frame rotated (control z -> base x), varying the mass
357404
// in control z should affect the response to force applied in base x direction
358405
TEST_F(MassMatrixTransformationTest, mass_transformation_affects_base_frame_response)

0 commit comments

Comments
 (0)