Skip to content
Open
Changes from 3 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
27 changes: 24 additions & 3 deletions src/libopenrave/kinbody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2274,19 +2274,40 @@ void KinBody::SetDOFValues(const dReal* pJointValues, int dof, uint32_t checklim
int expecteddof = dofindices.size() > 0 ? (int)dofindices.size() : GetDOF();
OPENRAVE_ASSERT_OP_FORMAT((int)dof,>=,expecteddof, "env=%s, body '%s' not enough values %d<%d", GetEnv()->GetNameId()%GetName()%dof%GetDOF(),ORE_InvalidArguments);

GetDOFValues(_vTempJoints);
if( dofindices.size() > 0 ) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@Puttichai I wonder if there could be another fast path where dofindices.size() == expecteddof, and dofinidces contains all the indices of the robot (even if they are in a different order).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I see. Thank you for the suggestion. I made a change to skip GetDOFValues when dofindices already covers all dofs. Also updated test cases.

// user only set a certain number of indices, so have to fill the temporary array with the full set of values first
// and then overwrite with the user set values
GetDOFValues(_vTempJoints);
for(size_t i = 0; i < dofindices.size(); ++i) {
if( !std::isnan(pJointValues[i]) ) {
_vTempJoints.at(dofindices[i]) = pJointValues[i];
}
}
}
else {
for(size_t i = 0; i < _vTempJoints.size(); ++i) {
if( !std::isnan(pJointValues[i]) ) {
// In the common full-vector path, the inputs are copied verbatim into _vTempJoints, so the
// current values fetched by GetDOFValues() would be fully overwritten. GetDOFValues() is expensive
// (it recomputes every joint angle from the link transforms - quatMultiply + atan2 per dof), so only
// call it when an input is NaN, which is the sentinel meaning "keep the current value for that dof".
Comment thread
Puttichai marked this conversation as resolved.
Outdated
const int ndof = GetDOF();
Comment thread
Puttichai marked this conversation as resolved.
Outdated
_vTempJoints.resize(ndof);
bool bHasNaN = false;
for(int i = 0; i < ndof; ++i) {
if( std::isnan(pJointValues[i]) ) {
bHasNaN = true;
break;
}
}
if( bHasNaN ) {
GetDOFValues(_vTempJoints);
for(int i = 0; i < ndof; ++i) {
if( !std::isnan(pJointValues[i]) ) {
_vTempJoints[i] = pJointValues[i];
}
}
}
else {
for(int i = 0; i < ndof; ++i) {
Comment thread
Puttichai marked this conversation as resolved.
Outdated
_vTempJoints[i] = pJointValues[i];
}
}
Expand Down
Loading