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
getting full path for component in C++
- Colin Smith
- Posts: 53
- Joined: Fri Feb 24, 2012 11:50 am
- Thomas Uchida
- Posts: 1800
- Joined: Wed May 16, 2012 11:40 am
Re: getting full path for component in C++
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.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?
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
- Colin Smith
- Posts: 53
- Joined: Fri Feb 24, 2012 11:50 am
Re: getting full path for component in C++
Ok, thanks for clarifying.
Colin
Colin
- Colin Smith
- Posts: 53
- Joined: Fri Feb 24, 2012 11:50 am
Re: getting full path for component in C++
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
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