Skip to content
Merged
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
379 changes: 54 additions & 325 deletions .github/workflows/continuous_integration.yml

Large diffs are not rendered by default.

38 changes: 7 additions & 31 deletions Applications/CMC/test/testCMCGait10dof18musc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,7 @@

using namespace OpenSim;

TEST_CASE("testGait10dof18musc (Windows)", "[win]") {
CMCTool cmc("gait10dof18musc_Setup_CMC.xml");
cmc.run();

const TimeSeriesTable results(
"gait10dof18musc_ResultsCMC/walk_subject_states.sto");
const TimeSeriesTable std(
"gait10dof18musc_std_walk_subject_states_win.sto");

// TODO: Replace with macro from OpenSim/Moco/Test/Testing.h
const auto& actual = results.getMatrix();
const auto& expected = std.getMatrix();
REQUIRE((actual.nrow() == expected.nrow()));
REQUIRE((actual.ncol() == expected.ncol()));
for (int ir = 0; ir < actual.nrow(); ++ir) {
for (int ic = 0; ic < actual.ncol(); ++ic) {
INFO("(" << ir << "," << ic << "): " << actual.getElt(ir, ic) <<
" vs " << expected.getElt(ir, ic));
REQUIRE((Catch::Approx(actual.getElt(ir, ic)).margin(1e-3)
== expected.getElt(ir, ic)));
}
}
}

TEST_CASE("testGait10dof18musc (Mac/Linux)", "[unix]") {
TEST_CASE("testGait10dof18musc") {
CMCTool cmc("gait10dof18musc_Setup_CMC.xml");
cmc.run();

Expand All @@ -62,12 +38,12 @@ TEST_CASE("testGait10dof18musc (Mac/Linux)", "[unix]") {
const TimeSeriesTable std(
"gait10dof18musc_std_walk_subject_states_unix.sto");

// Unix systems produce inconsistent results compared to Windows. Somehow,
// CMC produces results with differing number of time points, so we need to
// interpolate the results to the same time points as the standard results.
// The shapes of the muscle activity curves also differ slightly, so we
// allow a larger margin of error for the muscle activity curves. Therefore,
// this is a weaker test compared to the Windows test.
// CMC produces results with differing number of time points on different
// systems, so we need to interpolate the results to the same time points as
// the standard results. The shapes of the muscle activity curves also
// differ slightly, so we allow a larger margin of error for the muscle
// activity curves. Therefore, this is a weaker test compared to other
// CMC tests.
GCVSplineSet resultSplines(results);
GCVSplineSet stdSplines(std);

Expand Down
106 changes: 41 additions & 65 deletions Bindings/SWIGSimTK/Mat.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@

#include "SimTKcommon/internal/common.h"

#include <tuple>
#include <type_traits>

namespace SimTK {

/** This class represents a small matrix whose size is known at compile time,
Expand Down Expand Up @@ -336,71 +339,36 @@ template <int M, int N, class ELT, int CS, int RS> class Mat {
explicit Mat(int i)
{ new (this) Mat(ELT(Precision(i))); }

// A bevy of constructors from individual exact-match elements IN ROW ORDER.
Mat(const ELT& e0,const ELT& e1)
{assert(M*N==2);d[rIx(0)]=e0;d[rIx(1)]=e1;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2)
{assert(M*N==3);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3)
{assert(M*N==4);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4)
{assert(M*N==5);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4,
const ELT& e5)
{assert(M*N==6);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
d[rIx(5)]=e5;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4,
const ELT& e5,const ELT& e6)
{assert(M*N==7);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
d[rIx(5)]=e5;d[rIx(6)]=e6;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4,
const ELT& e5,const ELT& e6,const ELT& e7)
{assert(M*N==8);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4,
const ELT& e5,const ELT& e6,const ELT& e7,const ELT& e8)
{assert(M*N==9);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4,
const ELT& e5,const ELT& e6,const ELT& e7,const ELT& e8,const ELT& e9)
{assert(M*N==10);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4,
const ELT& e5,const ELT& e6,const ELT& e7,const ELT& e8,const ELT& e9,
const ELT& e10)
{assert(M*N==11);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4,
const ELT& e5,const ELT& e6,const ELT& e7,const ELT& e8,const ELT& e9,
const ELT& e10, const ELT& e11)
{assert(M*N==12);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
d[rIx(11)]=e11;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4,
const ELT& e5,const ELT& e6,const ELT& e7,const ELT& e8,const ELT& e9,
const ELT& e10, const ELT& e11, const ELT& e12)
{assert(M*N==13);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
d[rIx(11)]=e11;d[rIx(12)]=e12;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4,
const ELT& e5,const ELT& e6,const ELT& e7,const ELT& e8,const ELT& e9,
const ELT& e10, const ELT& e11, const ELT& e12, const ELT& e13)
{assert(M*N==14);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
d[rIx(11)]=e11;d[rIx(12)]=e12;d[rIx(13)]=e13;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4,
const ELT& e5,const ELT& e6,const ELT& e7,const ELT& e8,const ELT& e9,
const ELT& e10, const ELT& e11, const ELT& e12, const ELT& e13, const ELT& e14)
{assert(M*N==15);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
d[rIx(11)]=e11;d[rIx(12)]=e12;d[rIx(13)]=e13;d[rIx(14)]=e14;}
Mat(const ELT& e0,const ELT& e1,const ELT& e2,const ELT& e3,const ELT& e4,
const ELT& e5,const ELT& e6,const ELT& e7,const ELT& e8,const ELT& e9,
const ELT& e10, const ELT& e11, const ELT& e12, const ELT& e13, const ELT& e14,
const ELT& e15)
{assert(M*N==16);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
d[rIx(11)]=e11;d[rIx(12)]=e12;d[rIx(13)]=e13;d[rIx(14)]=e14;d[rIx(15)]=e15;}
#ifndef SWIG
// Constructs a `Mat` from individual exact-match elements IN ROW ORDER.
template<
typename... Elements,
typename = std::enable_if_t<
(M*N==sizeof...(Elements)) &&
(std::is_convertible_v<Elements&&, const E&> && ...)
>
>
Mat(Elements&&... elementsRowByRow)
{
assignDataRowByRow(
std::forward_as_tuple(elementsRowByRow...),
std::make_integer_sequence<int, sizeof...(Elements)>{}
);
}
#else
template <int MM = M, int NN = N,
typename std::enable_if<(MM==3 && NN==3), int>::type = 0>
Mat(const E& e00, const E& e01, const E& e02,
const E& e10, const E& e11, const E& e12,
const E& e20, const E& e21, const E& e22)
{
const E elems[9] = {e00, e01, e02,
e10, e11, e12,
e20, e21, e22};
for (int idx = 0; idx < 9; ++idx)
d[rIx(idx)] = elems[idx];
}
#endif

#ifndef SWIG
// Construction from 1-6 *exact match* Rows
Expand Down Expand Up @@ -1199,6 +1167,14 @@ template <int M, int N, class ELT, int CS, int RS> class Mat {
const int col = k % N; // that's modulus, not cross product!
return row*RS + col*CS;
}

#ifndef SWIG
template<typename ElementsRowByRowTuple, int... Idx>
void assignDataRowByRow(ElementsRowByRowTuple&& els, std::integer_sequence<int, Idx...>)
{
((d[rIx(Idx)] = std::get<Idx>(els)) , ...);
}
#endif
};

//////////////////////////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion Bindings/SWIGSimTK/Vec.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class Vec {
NRows = M,
NCols = 1,
NPackedElements = M,
NActualElements = M * STRIDE, // includes trailing gap
NActualElements = (M-1)*STRIDE + 1, // no trailing gap
NActualScalars = CNT<E>::NActualScalars * NActualElements,
RowSpacing = STRIDE,
ColSpacing = NActualElements,
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ performance and stability in wrapping solutions.
- Added `Component::removeComponent` and `Component::extractComponent` methods, which enable removing subcomponents that were previously added via `Component::addComponent` or the `<components>` XML element (#4174).
- Updated required language level to C++20. (#3929)
- Breaking: removed the `operator==` and `operator<` overloads in `ControlLinearNode` and replaced usages with the equivalent utility functions `isEqual()` and `isLessThan()`. (#4095)
- Made various changes to support builds on Ubuntu 24.04 with GCC 13. (#4186)


v4.5.2
Expand Down
12 changes: 6 additions & 6 deletions OpenSim/Analyses/Test/testOutputReporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,9 @@ void simulateMuscle(
TimeSeriesTable_<SimTK::SpatialVec> tableSV("testOutputReporter_OutputsSpatialVec.sto");

double val_t0 = tableD.getIndependentColumn()[0];
const SimTK::Real& val_ke0 = tableD.getRowAtIndex(0)[0];
const Vec3& val_omega0 = tableV3.getRowAtIndex(0)[1];
const SimTK::SpatialVec& val_jrf0 = tableSV.getRowAtIndex(0)[1];
const SimTK::Real val_ke0 = tableD.getRowAtIndex(0)[0];
const Vec3 val_omega0 = tableV3.getRowAtIndex(0)[1];
const SimTK::SpatialVec val_jrf0 = tableSV.getRowAtIndex(0)[1];

CHECK_THAT(t0, Catch::Matchers::WithinAbs(val_t0, SimTK::Eps));
CHECK_THAT(ke0, Catch::Matchers::WithinAbs(val_ke0, SimTK::Eps));
Expand All @@ -229,9 +229,9 @@ void simulateMuscle(
}

double val_tf = tableD.getIndependentColumn()[tableD.getNumRows() - 1];
const SimTK::Real& val_ke = tableD.getRowAtIndex(tableD.getNumRows() - 1)[0];
const Vec3& val_omega = tableV3.getRowAtIndex(tableV3.getNumRows() - 1)[1];
const SimTK::SpatialVec& val_jrf =
const SimTK::Real val_ke = tableD.getRowAtIndex(tableD.getNumRows() - 1)[0];
const Vec3 val_omega = tableV3.getRowAtIndex(tableV3.getNumRows() - 1)[1];
const SimTK::SpatialVec val_jrf =
tableSV.getRowAtIndex(tableSV.getNumRows() - 1)[1];

model.realizeReport(state);
Expand Down
6 changes: 4 additions & 2 deletions OpenSim/Simulation/Wrap/PathWrapPoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ void OpenSim::PathWrapPoint::extendAddToSystem(SimTK::MultibodySystem& system) c
{
Super::extendAddToSystem(system);

_wrapPath = addCacheVariable("wrap_path", Array<SimTK::Vec3>{}, SimTK::Stage::Position);
_wrapPath = addCacheVariable("wrap_path",
Array<SimTK::Vec3>(SimTK::Vec3(SimTK::NaN), 0, 1),
SimTK::Stage::Position);
_wrapPathLength = addCacheVariable("wrap_path_length", 0.0, SimTK::Stage::Position);
_location = addCacheVariable("wrap_location", SimTK::Vec3{}, SimTK::Stage::Position);
_location = addCacheVariable("wrap_location", SimTK::Vec3(SimTK::NaN), SimTK::Stage::Position);
}

const OpenSim::WrapObject* OpenSim::PathWrapPoint::getWrapObject() const
Expand Down
71 changes: 32 additions & 39 deletions OpenSim/Simulation/Wrap/WrapResult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,47 +32,40 @@
using namespace std;
using namespace OpenSim;

WrapResult::WrapResult(const WrapResult& other) {
copyData(other);
}

//_____________________________________________________________________________
/**
* Copy data members from one WrapResult to another.
*
* @param aWrapResult WrapResult to be copied.
*/
void WrapResult::copyData(const WrapResult& aWrapResult) {
wrap_pts = aWrapResult.wrap_pts;
wrap_path_length = aWrapResult.wrap_path_length;

startPoint = aWrapResult.startPoint;
endPoint = aWrapResult.endPoint;

int i;
for (i = 0; i < 3; i++) {
r1[i] = aWrapResult.r1[i];
r2[i] = aWrapResult.r2[i];
c1[i] = aWrapResult.c1[i];
sv[i] = aWrapResult.sv[i];
}
WrapResult::WrapResult()
: startPoint{-1},
endPoint{-1},
wrap_pts{SimTK::Vec3(SimTK::NaN), 0, 1},
wrap_path_length{SimTK::NaN},
r1{SimTK::Vec3(SimTK::NaN)},
r2{SimTK::Vec3(SimTK::NaN)},
c1{SimTK::Vec3(SimTK::NaN)},
sv{SimTK::Vec3(SimTK::NaN)} {}

singleWrap = aWrapResult.singleWrap;
// TODO: Should factor be omitted from the copy?
}
WrapResult::WrapResult(const WrapResult& other)
: startPoint{other.startPoint},
endPoint{other.endPoint},
wrap_pts{other.wrap_pts},
wrap_path_length{other.wrap_path_length},
r1{other.r1},
r2{other.r2},
c1{other.c1},
sv{other.sv},
factor{SimTK::NaN},
singleWrap{other.singleWrap} {}

//=============================================================================
// OPERATORS
//=============================================================================
//_____________________________________________________________________________
/**
* Assignment operator.
*
* @return Reference to this object.
*/
WrapResult& WrapResult::operator=(const WrapResult& aWrapResult) {
if (this != &aWrapResult) {
copyData(aWrapResult);
WrapResult& WrapResult::operator=(const WrapResult& other) {
if (this != &other) {
startPoint = other.startPoint;
endPoint = other.endPoint;
wrap_pts = other.wrap_pts;
wrap_path_length = other.wrap_path_length;
r1 = other.r1;
r2 = other.r2;
c1 = other.c1;
sv = other.sv;
factor = SimTK::NaN;
singleWrap = other.singleWrap;
}

return *this;
Expand Down
5 changes: 1 addition & 4 deletions OpenSim/Simulation/Wrap/WrapResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,11 @@ class OSIMSIMULATION_API WrapResult
// CONSTRUCTION
//--------------------------------------------------------------------------
public:
WrapResult() = default;
WrapResult();
virtual ~WrapResult() = default;
WrapResult(const WrapResult& other);
WrapResult& operator=(const WrapResult& aWrapResult);

private:
void copyData(const WrapResult& aWrapResult);

//=============================================================================
}; // END of class WrapResult
//=============================================================================
Expand Down
2 changes: 1 addition & 1 deletion dependencies/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ AddDependency(NAME ezc3d
AddDependency(NAME simbody
DEFAULT ON
GIT_URL https://github.com/simbody/simbody.git
GIT_TAG 77bf63c030e4c30112952602abe120afedbdb1e6
GIT_TAG f9ab12cbad9d0da106473259d34c50577f934f49
CMAKE_ARGS -DBUILD_EXAMPLES:BOOL=OFF
-DBUILD_TESTING:BOOL=OFF
${SIMBODY_EXTRA_CMAKE_ARGS})
Expand Down
Loading