Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undo binding of model getCoordinatesInMultibodyTreeOrder and introduc… #3666

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Bindings/Python/tests/test_opensense.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ def test_createObjects(self):
constraint_var = .0001
ikSolver = osim.InverseKinematicsSolver(model, mRefs, oRefs, coordinateReferences, constraint_var)
print("Created InverseKinematicsSolver object..")
oRefs = osim.BufferedOrientationsReference()
print("Created BufferedOrientationsReference object..")
ikSolver = osim.InverseKinematicsSolver(model, mRefs, oRefs, coordinateReferences, constraint_var)
print("Created InverseKinematicsSolver object with BufferedOrientationsReference..")

def test_vector_rowvector(self):
print()
Expand All @@ -43,3 +47,19 @@ def test_vector_rowvector(self):
col[1] == row[1] and
col[2] == row[2] and
col[3] == row[3])

def test_BufferedOrientationReferencePut(self):
# Make sure that we can append new data to the BufferedOrientationReference object
quatTable = osim.TimeSeriesTableQuaternion(os.path.join(test_dir,'orientation_quats.sto'))
print("Created TimeSeriesTableQuaternion object..")
orientationsData = osim.OpenSenseUtilities.convertQuaternionsToRotations(quatTable)
print("Convert Quaternions to orientationsData")
time = 0
rowVecView = orientationsData.getNearestRow(time)
print("Sliced orientationData")
rowVec = osim.RowVectorRotation(rowVecView)
print("Converted slice to row vector")
oRefs = osim.BufferedOrientationsReference()
print("Created BufferedOrienationReference object")
oRefs.putValues(time, rowVec)
print("Added row vector to BufferedOrientationReference object")
5 changes: 5 additions & 0 deletions Bindings/Python/tests/test_simbody.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ def test_SimbodyMatterSubsystem(self):
assert (smss.calcSystemMassCenterLocationInGround(s)[2] ==
model.calcMassCenterPosition(s)[2])

coordNames = model.getCoordinateNamesInMultibodyTreeOrder();
print('firstCoord', coordNames.getElt(0));

J = osim.Matrix()
smss.calcSystemJacobian(s, J)
# 6 * number of mobilized bodies
Expand Down Expand Up @@ -248,3 +251,5 @@ def test_SimbodyMatterSubsystem(self):
assert residual.size() == s.getNU()
for i in range(residual.size()):
assert abs(residual[i]) < 1e-10


3 changes: 0 additions & 3 deletions Bindings/simulation.i
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,6 @@ OpenSim::ModelComponentSet<OpenSim::Controller>;
%include <OpenSim/Simulation/Model/ModelVisualPreferences.h>
%include <OpenSim/Simulation/Model/ModelVisualizer.h>
%copyctor OpenSim::Model;
%include <SimTKcommon/internal/ReferencePtr.h>
%template(ReferencePtrCoordinate) SimTK::ReferencePtr<const OpenSim::Coordinate>;
%template(StdVectorReferencePtrCoordinate) std::vector<SimTK::ReferencePtr<const OpenSim::Coordinate>>;
%include <OpenSim/Simulation/Model/Model.h>

%include <OpenSim/Simulation/Model/AbstractPathPoint.h>
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ and `Blankevoort1991Ligament`, usages of `get_GeometryPath`, `upd_GeometryPath`,
- Deleting elements from an `OpenSim::Coordinate` range now throws an exception during `finalizeFromProperties` (previously:
it would let you do it, and throw later when `Coordinate::getMinRange()` or `Coordinate::getMaxRange()` were called, #3532)
- Added `FunctionBasedPath`, a class for representing paths in `Force`s based on `Function` objects (#3389)
- Fixed bindings to expose the method Model::getCoordinatesInMultibodyTreeOrder to scripting users (#3569)
- Introduced the method `Model::getCoordinateNamesInMultibodyTreeOrder` for convenient access to internal coordinate ordering for scripting users (#3569)
- Fixed a bug where constructing a `ModelProcessor` from a `Model` object led to an invalid `Model`
- Added `LatinHypercubeDesign`, a class for generating Latin hypercube designs using random and algorithm methods (#3570)
- Refactor c3dExport.m file as a Matlab function (#3501), also expose method to allow some operations on tableColumns
Expand All @@ -41,6 +41,7 @@ and `Blankevoort1991Ligament`, usages of `get_GeometryPath`, `upd_GeometryPath`,
- Exposed simbody methods to obtain GravityForces, MobilityForces and BodyForces (#3490)
- Simbody was updated such that the headers it transitively exposes to downstream projects are compatible with C++20 (#3619)
- Moved speed computation from `computeForce` in children of `ScalarActuator` to dedicated `getSpeed` function.
- Fix type problem with BufferedOrientationReference (#3415)


v4.4.1
Expand Down
8 changes: 4 additions & 4 deletions OpenSim/Simulation/BufferedOrientationsReference.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace OpenSim {
//=============================================================================
/**
* Subclass of OrientationsReference that handles live data by providing a DataQueue
* that allows clients to push data into and allows the InverseKinematicsSolver to
* that allows clients to push data into and allows the InverseKinematicsSolver to
* draw data from for solving.
* Ideally this would be templatized, allowing for all Reference classes to leverage it.
*
Expand Down Expand Up @@ -79,19 +79,19 @@ class OSIMSIMULATION_API BufferedOrientationsReference
SimTK::Array_<SimTK::Rotation_<double>>& values) const override;

/** add passed in values to data procesing Queue */
void putValues(double time, const SimTK::RowVector_<SimTK::Rotation>& dataRow);
void putValues(double time, const SimTK::RowVector_<SimTK::Rotation_<double>>& dataRow);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't SimTK::Rotation an alias for SimTK::Rotation_<SimTK::Real>, with SimTK::Real usually being an alias for double (i.e. the before and after are equivalent for OpenSim)?


double getNextValuesAndTime(
SimTK::Array_<SimTK::Rotation_<double>>& values) override;

virtual bool hasNext() const override { return !_finished; };

void setFinished(bool finished) {
void setFinished(bool finished) {
_finished = finished;
};
private:
// Use a specialized data structure for holding the orientation data
mutable DataQueue_<SimTK::Rotation> _orientationDataQueue;
mutable DataQueue_<SimTK::Rotation_<double>> _orientationDataQueue;
bool _finished{false};
//=============================================================================
}; // END of class BufferedOrientationsReference
Expand Down
8 changes: 8 additions & 0 deletions OpenSim/Simulation/Model/Model.h
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,14 @@ OpenSim_OBJECT_NONTEMPLATE_DEFS(Model, ModelComponent);
std::vector<SimTK::ReferencePtr<const OpenSim::Coordinate>>
getCoordinatesInMultibodyTreeOrder() const;

/** A variant of getCoordinatesInMultibodyTreeOrder that returns names for Scripting users */
SimTK::Array_<std::string> getCoordinateNamesInMultibodyTreeOrder() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imo, should be in .cpp file - there's no upside to inlining it (it's not templated, and it's doing a fairly large amount of work)

SimTK::Array_<std::string> namesArray;
auto coords = getCoordinatesInMultibodyTreeOrder();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coords is a std::vector<T>, so this can be rewritten as:

const auto coords = getCoordinatesInMultibodyTreeOrder();
SimTK::Array_<std::string> namesArray;
namesArray.reserve(coords.size());  // prevent a reallocation
for (const auto& coord : coords) {
    namesArray.push_back(coord.getName());
}

for (int i=0; i < (int)coords.size(); ++i)
namesArray.push_back(coords[i]->getName());
return namesArray;
}
/** Get a warning message if any Coordinates have a MotionType that is NOT
consistent with its previous user-specified value that existed in
Model files prior to OpenSim 4.0 */
Expand Down
3 changes: 3 additions & 0 deletions OpenSim/Simulation/Test/testAssemblySolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ void testAssembleModelWithConstraints(string modelFile)
for(int i=0; i< coords.getSize(); i++) {
cout << "Coordinate " << coords[i].getName() << " get value = " << coords[i].getValue(state) << endl;
}
auto coordsInOrder = model.getCoordinateNamesInMultibodyTreeOrder();
cout << coordsInOrder << std::endl;

assert(coords.getSize()==coordsInOrder.size());
// Initial coordinates after initial assembly
Vector q0 = state.getQ();

Expand Down
Loading