[Controller] Add MotionReplayController component to load a motion from csv file and apply it to a MechanicalObject#41
Conversation
src/InfinyToolkit/MotionReplayController/MotionReplayController.inl
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.h
Outdated
Show resolved
Hide resolved
|
I guess the closing is a wrong manipulation? |
|
Since the PR was open, and I made some modifications, including changing the base class. I thought it might be cleaner to open a clean PR. Except if you want to follow the history of the changes. |
|
You can keep the same PR as in any case we only review the change in files which is the final diff between your branch and master: https://github.com/InfinyTech3D/InfinyToolkit/pull/41/changes |
|
I conclude that using the SOFA controller slightly increases the FPS. I compared Scenario 2 for Asan#2 at three stages:
--> The approximate FPS values are: Python controller: 66, 37, 22 SOFA controller: 70, 39, 25 |
src/InfinyToolkit/MotionReplayController/MotionReplayController.h
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.h
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.inl
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.cpp
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.h
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.h
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.h
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.inl
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.h
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.h
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.inl
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.inl
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.inl
Outdated
Show resolved
Hide resolved
|
Finishing the implementation of the controller depends on #44 |
|
The component is independent from the breathing as the goal is to make it generic. I think with the list of indices it is good. |
|
The breathing option was added to the Motion Replay Controller through a boolean breathing flag. I think it is better to keep the breathing deformation within this controller, since it overwrites the grid's MO too. |
src/InfinyToolkit/MotionReplayController/MotionReplayController.inl
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.h
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.inl
Outdated
Show resolved
Hide resolved
src/InfinyToolkit/MotionReplayController/MotionReplayController.inl
Outdated
Show resolved
Hide resolved
|
|
||
| double currentTime = this->getContext()->getTime(); | ||
| // Compute frame index based on the current time and DVF time step | ||
| size_t dvfIndex = static_cast<size_t>(currentTime / d_dvfTimeStep.getValue()); |
There was a problem hiding this comment.
Regarding the time step: I initially planned to explicitly compare the scene time step with the one used for deformation recording and log a warning if they differed. But, I defined dvfIndex as it directly maps the current simulation time to the corresponding recorded frame, naturally handling any time step mismatch without requiring an explicit check. I think this way is better.
| if (fixedIndices.empty()) | ||
| { | ||
| msg_warning() << "No fixed indices provided."; | ||
| return; | ||
| } |
There was a problem hiding this comment.
| if (fixedIndices.empty()) | |
| { | |
| msg_warning() << "No fixed indices provided."; | |
| return; | |
| } |
for me this is just an additional feature so empty array is possible
| std::unordered_set<unsigned int> fixedSet( | ||
| fixedIndices.begin(), | ||
| fixedIndices.end() | ||
| ); | ||
|
|
There was a problem hiding this comment.
| std::unordered_set<unsigned int> fixedSet( | |
| fixedIndices.begin(), | |
| fixedIndices.end() | |
| ); |
no need to copy the array
| positions[i][0] = frames[currentIndex][i][0]; | ||
| positions[i][1] = frames[currentIndex][i][1]; | ||
| positions[i][2] = frames[currentIndex][i][2]; | ||
|
|
||
| if (fixedSet.find(static_cast<unsigned int>(i)) == fixedSet.end()) | ||
| { | ||
| int axis = d_displacementAxis.getValue(); // 0=X, 1=Y, 2=Z | ||
| positions[i][1] += offset; | ||
| } |
There was a problem hiding this comment.
| positions[i][0] = frames[currentIndex][i][0]; | |
| positions[i][1] = frames[currentIndex][i][1]; | |
| positions[i][2] = frames[currentIndex][i][2]; | |
| if (fixedSet.find(static_cast<unsigned int>(i)) == fixedSet.end()) | |
| { | |
| int axis = d_displacementAxis.getValue(); // 0=X, 1=Y, 2=Z | |
| positions[i][1] += offset; | |
| } | |
| auto it = std::find(fixedIndices.begin(), fixedIndices.end(), i); | |
| if (it != fixedIndices.end()) | |
| continue; | |
| positions[i][0] = frames[currentIndex][i][0]; | |
| positions[i][1] = frames[currentIndex][i][1]; | |
| positions[i][2] = frames[currentIndex][i][2]; | |
| if (offset != 0.0) | |
| { | |
| int axis = d_displacementAxis.getValue(); // 0=X, 1=Y, 2=Z | |
| positions[i][axis] += offset; | |
| } |
you might need to add: #include
This controller inherits from MechanicalStateController, allowing easy access to the mechanical object’s states after loading all frames at initialization from a CSV file.
The class introduces two new functions:
loadMotion() – Loads all frames from the CSV and stores them in a vector.
handleEvent() – Updates the mechanical object’s positions (grids) according to the loaded frames at each animation step.
However, while compiling SOFA (which includes the infiny toolkit), there is a linking issue: It seems it
cannot inherit from MechanicalStateController and the plugin does not compile. I might have missed some steps to properly register this component inside the InfinyToolkit.
P.S. I have updated SOFA from the master branch.