Page 1 of 1

getting full path for component in C++

Posted: Tue Sep 18, 2018 3:07 am
by clnsmith
Hi all,

I'm working on implementing a simulation tool in C++ (OpenSim 4.0) that treats coordinates in the model differently.

So I have an .xml file with list properties of "Primary" coordinates and "Secondary" coordinates that I read in as strings.

I need to get the value of each of the Secondary components so I have a loop:

for (int i = 0; i < n_secondary_coord; ++i){
std::string name = get_secondary_coordinates(i);
values(i) = _model.getComponent<Coordinate>(name).getValue(state);
}

I am getting the error:
Component 'FBKNEE' could not find 'knee_add_r' of type Coordinate. Make sure a component exists at this path and that it is of the correct type.

because in the input .xml file I only list the names of the coordinates rather than the full path.

https://github.com/opensim-org/opensim-core/issues/1025

I read through this issue ^.

Is there a way to use _model.findComponent() (I get an error, because it is protected) or _model.printComponentsMatching (returns an unsigned int, not a std::string needed for getComponent) to get the full path for _model.getComponent()?

Or should I require the user to put a full path in the input file? This feels clunkier to me, but maybe you are necessitating it so you can have coordinates with the same name?

Thanks,
Colin

Re: getting full path for component in C++

Posted: Tue Sep 18, 2018 11:53 am
by tkuchida
Or should I require the user to put a full path in the input file? This feels clunkier to me, but maybe you are necessitating it so you can have coordinates with the same name?
The design of 4.0 permits duplicate Component names provided the absolute paths are unique. Some of the existing code still assumes that unique names have been used (e.g., for Coordinates), but this code will eventually be updated.

In your case, perhaps you could suggest that users provide the absolute path; if only the name is provided, you could search for it yourself (e.g., see below) and throw an exception if the number of matches is not exactly 1.

Code: Select all

unsigned numMatches = 0;
for (const auto& coord : getComponentList<Coordinate>()) {
    // increment numMatches if coord.getName() matches string provided by user
}
// throw exception if numMatches != 1

Re: getting full path for component in C++

Posted: Wed Sep 19, 2018 2:24 am
by clnsmith
Ok, thanks for clarifying.

Colin

Re: getting full path for component in C++

Posted: Wed Sep 19, 2018 1:58 pm
by clnsmith
Just an observation in case someone runs into issues with a similar setup

for (Coordinate& coord : _model.updComponentList<Coordinate>()) {
std::cout << coord.getAbsolutePathString() << std::endl;
}

will give a different result than using a non referenced Coordinate iterator or the getComponentList function:

for (Coordinate coord : _model.updComponentList<Coordinate>()) {
std::cout << coord.getAbsolutePathString() << std::endl;
}

for (Coordinate coord : _model.getComponentList<Coordinate>()) {
std::cout << coord.getAbsolutePathString() << std::endl;
}

The first case will return the full path in the model:
/Model/Joint/Coordinate

While the second two cases the coordinates are now independent of the model so they return:
/Coordinate