Skip to content

Commit 31a0b7a

Browse files
authored
Merge pull request #273 from EtienneAr/fix_removeRigidContact
Fix removeRigidContact
2 parents 6c21e3b + e43b381 commit 31a0b7a

File tree

5 files changed

+41
-1
lines changed

5 files changed

+41
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
- Fix value of nEq when removeRigidContact for contact with priority > 0
11+
1012
## [1.8.0] - 2025-03-29
1113

1214
- Fix missing `const` specifier in python bindings for methods `RobotInertia.set_rotor_inertia()`

include/tsid/formulations/inverse-dynamics-formulation-acc-force.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ class InverseDynamicsFormulationAccForce
105105
Vector getContactForces(const std::string& name, const HQPOutput& sol);
106106
bool getContactForces(const std::string& name, const HQPOutput& sol,
107107
RefVector f) override;
108+
unsigned int getTaskPriority(const std::string& name) override;
108109

109110
public:
110111
template <class TaskLevelPointer>

include/tsid/formulations/inverse-dynamics-formulation-base.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ class InverseDynamicsFormulationBase {
157157
virtual bool getContactForces(const std::string& name, const HQPOutput& sol,
158158
RefVector f) = 0;
159159

160+
virtual unsigned int getTaskPriority(const std::string& name) = 0;
161+
160162
protected:
161163
std::string m_name;
162164
RobotWrapper m_robot;

src/formulations/inverse-dynamics-formulation-acc-force.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,9 @@ bool InverseDynamicsFormulationAccForce::removeRigidContact(
541541
return false;
542542
}
543543

544+
// Find motion task priority
545+
bool is_motion_contraint =
546+
(getTaskPriority(contactName + "_motion_task") == 0);
544547
bool first_constraint_found = removeFromHqpData(contactName + "_motion_task");
545548
assert(first_constraint_found);
546549

@@ -556,7 +559,7 @@ bool InverseDynamicsFormulationAccForce::removeRigidContact(
556559
for (auto it = m_contacts.begin(); it != m_contacts.end(); it++) {
557560
if ((*it)->contact.name() == contactName) {
558561
m_k -= (*it)->contact.n_force();
559-
m_eq -= (*it)->motionConstraint->rows();
562+
if (is_motion_contraint) m_eq -= (*it)->motionConstraint->rows();
560563
m_in -= (*it)->forceConstraint->rows();
561564
m_contacts.erase(it);
562565
resizeHqpData();
@@ -600,3 +603,17 @@ bool InverseDynamicsFormulationAccForce::removeFromHqpData(
600603
}
601604
return false;
602605
}
606+
607+
unsigned int InverseDynamicsFormulationAccForce::getTaskPriority(
608+
const std::string &name) {
609+
for (std::size_t i = 0; i < m_hqpData.size(); i++) {
610+
const bool found = std::any_of(
611+
m_hqpData[i].begin(), m_hqpData[i].end(),
612+
[&name](const auto &c) { return c.second->name() == name; });
613+
if (found) {
614+
return i;
615+
}
616+
}
617+
assert(false); // Task name not found in formulation data
618+
return -1;
619+
}

tests/tsid-formulation.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,15 @@ BOOST_AUTO_TEST_CASE(test_invdyn_formulation_acc_force_remove_contact) {
322322
CHECK_LESS_THAN(v.norm(), 1e6);
323323
}
324324

325+
// Removing contact constraint should decrease nb of equality by 6
326+
int nEq = tsid->nEq();
327+
tsid->removeRigidContact("contact_rfoot");
328+
nEq -= 6;
329+
BOOST_CHECK_EQUAL(nEq, tsid->nEq());
330+
tsid->removeRigidContact("contact_lfoot");
331+
nEq -= 6;
332+
BOOST_CHECK_EQUAL(nEq, tsid->nEq());
333+
325334
delete solver;
326335
cout << "\n### TEST FINISHED ###\n";
327336
PRINT_VECTOR(v);
@@ -573,6 +582,7 @@ BOOST_AUTO_TEST_CASE(test_contact_point_invdyn_formulation_acc_force) {
573582
Vector3 contactNormal = Vector3::UnitZ();
574583
std::vector<std::shared_ptr<ContactPoint>> contacts(4);
575584

585+
int nEq = tsid->nEq();
576586
for (int i = 0; i < 4; i++) {
577587
auto cp = std::make_shared<ContactPoint>("contact_" + contactFrames[i],
578588
robot, contactFrames[i],
@@ -584,6 +594,9 @@ BOOST_AUTO_TEST_CASE(test_contact_point_invdyn_formulation_acc_force) {
584594
cp->useLocalFrame(false);
585595
tsid->addRigidContact(*cp, w_forceReg, 1.0, 1);
586596

597+
// Adding rigid contact as cost should not change nb of equalities
598+
BOOST_CHECK_EQUAL(nEq, tsid->nEq());
599+
587600
contacts[i] = cp;
588601
}
589602

@@ -650,10 +663,15 @@ BOOST_AUTO_TEST_CASE(test_contact_point_invdyn_formulation_acc_force) {
650663
CHECK_LESS_THAN(v.norm(), 1e6);
651664
}
652665

666+
nEq = tsid->nEq();
653667
for (int i = 0; i < 4; i++) {
654668
Eigen::Matrix<double, 3, 1> f;
655669
tsid->getContactForces(contacts[i]->name(), *sol, f);
656670
cout << contacts[i]->name() << " force:" << f.transpose() << endl;
671+
672+
// Removing rigid contact (added as cost) should not change nb of equalities
673+
tsid->removeRigidContact(contacts[i]->name());
674+
BOOST_CHECK_EQUAL(nEq, tsid->nEq());
657675
}
658676

659677
delete solver;

0 commit comments

Comments
 (0)