CoordinateCouplerConstraint with multiple independent coordinates
Posted: Tue Dec 15, 2020 11:36 pm
The OpenSim::CoordinateCouplerConstraint appears to support multiple independent coordinates, however, when I actually tried to use this I get an assertion error:
coordIndices.size() is equal to 3 (2 independent + 1 dependent), but function->getArgumentSize() returns 2. From reading the code it looks like the issue is that CoordinateCouplerConstraint uses a CompoundFunction class internally, for which getArgumentSize() is hardcoded to 2 (1 independent + 1 dependent). I would've expected this to be N independent + 1 dependent? However, I'm not certain if this is a correct conclusion or if I'm simply using the API incorrectly? (hence why I opted for a forum post rather than a Github issue)
For context, my code looks something like this:
Code: Select all
Constraint::CoordinateCouplerImpl::CoordinateCouplerImpl
(SimbodyMatterSubsystem& matter,
const Function* function,
const Array_<MobilizedBodyIndex>& coordMobod,
const Array_<MobilizerQIndex>& coordQIndex)
: Implementation(matter, 1, 0, 0), function(function),
coordBodies(coordMobod.size()), coordIndices(coordQIndex),
temp(coordBodies.size()), referenceCount(new int[1])
{
assert(coordBodies.size() == coordIndices.size());
assert(coordIndices.size() == function->getArgumentSize()); <------- Assertion error
assert(function->getMaxDerivativeOrder() >= 2);
referenceCount[0] = 1;
for (int i = 0; i < (int)coordBodies.size(); ++i) {
const MobilizedBody& mobod = matter.getMobilizedBody(coordMobod[i]);
coordBodies[i] = addConstrainedMobilizer(mobod);
}
}
For context, my code looks something like this:
Code: Select all
OpenSim::Array<std::string> independentCoordinateNames;
OpenSim::Array<double> coefficients;
for (const auto& coupling : couplings)
{
independentCoordinateNames.append(...));
coefficients.append(...);
}
coefficients.append(0.0); // constant
auto* constraint = new OpenSim::CoordinateCouplerConstraint();
constraint->setIndependentCoordinateNames(independentCoordinateNames);
constraint->setDependentCoordinateName(coordinate.getName());
constraint->setFunction(OpenSim::LinearFunction(coefficients));
mModel->addConstraint(constraint);