Skip to content

Feature/dynamic model for mock interface - #14

Open
pvonwirth wants to merge 24 commits into
mainfrom
feature/dynamic_model_for_mock_interface
Open

Feature/dynamic model for mock interface#14
pvonwirth wants to merge 24 commits into
mainfrom
feature/dynamic_model_for_mock_interface

Conversation

@pvonwirth

Copy link
Copy Markdown
Contributor

Task: https://app.clickup.com/t/86ca8y8tj

Depending on whether you like what you see or not, we may wanna have some discussion about Coding Style, Naming, Dos, Don'ts, what so ever ...

@pvonwirth
pvonwirth requested a review from firesurfer June 17, 2026 11:41
{
using kinematics_translator = kinematics::KinematicsTranslator<kinematics_mapping>;

static constexpr bool IS_MOCK_ = is_dua_drive_interface_mock_v<DriveTypeT>;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

please do not use upper case letters as this will create confusion with macros.

Also (my style) I would move it into the public part of the class and remove the trailing _

// In case there are predefined positions for mock operation we enforce them
// This is a pure compile time statement
if constexpr (std::is_same_v<DriveTypeT, DuaDriveInterfaceMock>) {
if constexpr (IS_MOCK_) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

good idea to replace it like that

namespace duatic::duadrive_interface::dynamic_model
{

void DynamicModelNon::on_init(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I dont like the name. It is rather undescriptive.

Also I think for a single function I would not add a cpp file and keep it simply in the header

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

other suggestions?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The DynamicModelNon is bascially just for the standard mock case.

I would just call it like that ?
DynamicModelMock.

Please also see my argument below how I would actually setup the whole structure.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Renamed

namespace duatic::duadrive_interface::dynamic_model
{

void DynamicModelPinocchio::on_init(const hardware_interface::HardwareComponentInterfaceParams& system_info)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You do not need to resemble in your architecture the way a ros2 hardware interface component is built.
The reason the DuaDriveInterfaces are built like this is because they actually need to resemble the same lifestyle model.

But for this dynamic pinocchio model I don't think this is needed (it also creates quite a bit of overhead)

Also I think you could directly pass the urdf model which is created here:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Pass-by-reference, i.e. no overhead.
(Unlike the logger, which is copied all the way down to the base class)
The idea here was to just pass the entire description because we have and may one day wanna use other information inside ...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

But I change it to pass the urdf

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do as you find it fitting. My argument about overhead was about creating the urdf::Model twice btw.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Da hast du recht, das wird zweimal erzeugt.
Ist geändert.

* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "duatic_duadrive_interface/dynamic_model/dynamic_model_pinocchio.hpp"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In general just as a suggestion: I often avoid creating for every header file a cpp file especially if there is just like one function in there
Reason is: a) amount of files to manage b) in this case one could also argue performance

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@firesurfer Compile-time performance will be better with dedicated cpp files.
If you think about run-time performance, we can link with lto enabled (Link-time-Optimization) to allow function inlining across compilation units.
However, from what I see in the rest of the code, optimizing a single, non-conditional function call is absolutely not the level of optimization that is currently required or matters with respect to optimization potentials throughout the rest of the code.
However, I'm happy about your opinion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think I just come from the other way around. I tend to only add cpp files if I have to. It is more about code organisation overhead.

I can image that LTO might be troublesome if used in a plugin architecture.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In dem Moment wo du Header-Implementierungen schreibst zwingst du den Linker sowieso schon dazu LTO zu machen um den ganzen doppelten Code zu entfernen.
Also ich glaube was LTO angeht kann man dem Compiler durchaus trauen. (Hab ich aber selbst tatsächlich auch noch nie produktiv benutzt)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

empty cpp removed

void DuaDriveInterfaceMock::stage_mock_acceleration(const double acceleration)
{
mock_acceleration_ = acceleration;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Even though this is rather easy to implement this way I would say it might be better to implement it like this:

During creation of each DuaDriveInterfaceMock instance just pass a function pointer which allows each drive to obtain the necessary information from the dynamic model. I would also consider not just returning the acceleration but just the whole state for that specific actuator in that function. This already introduces the necessary infrastructure code for more complex simulation approaches

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@firesurfer
The Problem here is, that the drives themselves have nothing to do with the dynamic model.
Especially, due to the fact that the drives drive coupled kinematics and the model models decoupled kinematics.

@firesurfer firesurfer Jun 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

By using a function pointer you fully decouple it. Given that you also create a DynamicNonModel (which is basically -> do nothing) I would argue it is even more consistent to actually just have the Drive instances get that information from the Model and have less stuff in the DuaDriveInterfaceMock. This would even make it more consistent with the real hardware one could argue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Decoupled

@pvonwirth
pvonwirth requested a review from firesurfer June 23, 2026 15:27
/**
* @brief Register a mock dynamics model with the mock hardware
*/
void register_mock_dynamics(const std::function<double()>& acceleration_callback)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can you pass this via the ctr ?


target_link_libraries(duatic_duadrive_interface ${YAML_CPP_LIBRARIES})
target_link_libraries(duatic_duadrive_interface ${YAML_CPP_LIBRARIES}
pinocchio::pinocchio

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

move the pinnochio::pinocchio update to the target_link_libraries in line 40

In case we are on older platforms ament_target_dependencies should do the job

@firesurfer firesurfer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me. See my small comments of stuff to fix.

Before merging I would suggest we test this out with real hardware just to make sure that we didn't break anything (what I dont expect btw).

Also please test this change against all Duatic hardware components.
Is your plan to ship the DynamicModel as default ? What are the necessary steps in a downstream component to support this ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants