Measuring Contact Force in Forward Simulation
- Kenechukwu Mbanisi
- Posts: 51
- Joined: Fri Feb 10, 2017 2:50 pm
Measuring Contact Force in Forward Simulation
Hello there,
I am trying to study how the contact forces are applied on OpenSim. I have used contact spheres to model object-ground contact. It's modeled as an ElasticFoundationForce.
What I want to do is to be able to measure the contact force generated during simulation at every time-step. My goal is to eventually use this as a means of measuring the external force on my model for a force feedback controller.
Can I get any pointers on what methods/functions to use in obtaining this in the C++ API?
Thank you.
Kenechukwu
I am trying to study how the contact forces are applied on OpenSim. I have used contact spheres to model object-ground contact. It's modeled as an ElasticFoundationForce.
What I want to do is to be able to measure the contact force generated during simulation at every time-step. My goal is to eventually use this as a means of measuring the external force on my model for a force feedback controller.
Can I get any pointers on what methods/functions to use in obtaining this in the C++ API?
Thank you.
Kenechukwu
- Dimitar Stanev
- Posts: 1096
- Joined: Fri Jan 31, 2014 5:14 am
- Kenechukwu Mbanisi
- Posts: 51
- Joined: Fri Feb 10, 2017 2:50 pm
Re: Measuring Contact Force in Forward Simulation
Thank you very much, Dimitar.
I went through the example code and I have made a simple example using my model.
I find that the code throws an exception at the "system.realizeTopology()" line:
It seems like it is failing to realize the topology of the system. I am not sure what I am doing wrong here. Any pointers would be helpful.
Thank you.
Kenechukwu
I went through the example code and I have made a simple example using my model.
Code: Select all
class forceReport : public PeriodicEventReporter {
public:
forceReport(const MultibodySystem& system,
const CompliantContactSubsystem& contactForces,
Real reportInterval)
: PeriodicEventReporter(reportInterval), m_system(system), m_contactForces(contactForces) {}
void handleEvent(const State& state) const override {
m_system.realize(state, Stage::Dynamics);
const int ncont = m_contactForces.getNumContactForces(state);
for (int i = 0; i < ncont; ++i) {
const ContactForce& force = m_contactForces.getContactForce(state, i);
std::cout << force << std::endl;
}
}
private:
const MultibodySystem& m_system;
const CompliantContactSubsystem& m_contactForces;
};
int main()
{
try {
Model osimModel("my_model.osim");
State& s = osimModel.initSystem();
MultibodySystem system = osimModel.updMultibodySystem();
ContactTrackerSubsystem tracker(system);
CompliantContactSubsystem contactForces(system, tracker);
osimModel.buildSystem();
State& s_new = osimModel.initializeState();
system.addEventReporter(new forceReport(system, contactForces, 0.1));
const State& s_new = system.realizeTopology();
SimTK::RungeKuttaMersonIntegrator integrator(osimModel.getMultibodySystem());
integrator.setAccuracy(1.0e-3);
Manager manager(osimModel, integrator);
manager.setInitialTime(0.0); manager.setFinalTime(1.0);
manager.integrate(s_new);
Code: Select all
Exception thrown at 0x00007FFC4183472C (OpenSim_SimTKcommon.dll) in exampleController.exe: 0xC0000005: Access violation reading location 0x000003E0EFE6D1D0.
Thank you.
Kenechukwu
- Thomas Uchida
- Posts: 1792
- Joined: Wed May 16, 2012 11:40 am
Re: Measuring Contact Force in Forward Simulation
I haven't compiled your code to investigate in detail, but at first glance it looks like
In the first case, it looks like you are constructing a new MultibodySystem rather than fetching a writable reference to the MultibodySystem associated with osimModel.
Code: Select all
// this line
MultibodySystem system = osimModel.updMultibodySystem();
// should be
MultibodySystem& system = osimModel.updMultibodySystem();
- Kenechukwu Mbanisi
- Posts: 51
- Joined: Fri Feb 10, 2017 2:50 pm
Re: Measuring Contact Force in Forward Simulation
Thank you Tom.
I made that correction as well as some other few modifications. The system realizes to topology now, but the concern is that it throws an unknown exception at the "manager.integrate(s_new)" line.
I have added the code and the model here. Any pointers here would be very much appreciated.
Kenechukwu
I made that correction as well as some other few modifications. The system realizes to topology now, but the concern is that it throws an unknown exception at the "manager.integrate(s_new)" line.
Code: Select all
class forceReport : public PeriodicEventReporter {
public:
forceReport(const MultibodySystem& system,
const CompliantContactSubsystem& contactForces,
Real reportInterval)
: PeriodicEventReporter(reportInterval), m_system(system), m_contactForces(contactForces) {}
void handleEvent(const State& state) const override {
m_system.realize(state, Stage::Dynamics);
const int ncont = m_contactForces.getNumContactForces(state);
std::cout << ncont << std::endl;
for (int i = 0; i < ncont; ++i) {
const ContactForce& force = m_contactForces.getContactForce(state, i);
std::cout << force << std::endl;
}
}
private:
const MultibodySystem& m_system;
const CompliantContactSubsystem& m_contactForces;
};
int main()
{
try {
Model osimModel("my_model.osim");
State& s = osimModel.initSystem();
MultibodySystem& system = osimModel.updMultibodySystem();
ContactTrackerSubsystem tracker(system);
CompliantContactSubsystem contactForces(system, tracker);
State& s_new = osimModel.initializeState();
forceReport* conforceReporter = new forceReport(system, contactForces, 0.1);
system.addEventReporter(conforceReporter);
system.realizeTopology();
SimTK::RungeKuttaMersonIntegrator integrator(system);
integrator.setAccuracy(1.0e-3);
Manager manager(osimModel, integrator);
manager.setInitialTime(0.0); manager.setFinalTime(1.0);
manager.integrate(s_new);
}
Kenechukwu
- Attachments
-
- my_model with codes.zip
- (397.28 KiB) Downloaded 69 times
- Thomas Uchida
- Posts: 1792
- Joined: Wed May 16, 2012 11:40 am
Re: Measuring Contact Force in Forward Simulation
I don't think you should need State& s_new = osimModel.initializeState();. Is it possible to remove that line and call manager.integrate(system); instead?
- Kenechukwu Mbanisi
- Posts: 51
- Joined: Fri Feb 10, 2017 2:50 pm
Re: Measuring Contact Force in Forward Simulation
Hello Tom,
Thanks for the comment. I just tried that; it seems that the integrate method only takes values of type "SimTK::State&".
Here's the error I get: "a reference of type 'SimTK::State&' cannot be initialized with a value of type 'SimTK::MultibodySystem' "
I thought that it would be useful to initialize the state after we add the new subsystems to the multibodysystem.
Kenechukwu
Thanks for the comment. I just tried that; it seems that the integrate method only takes values of type "SimTK::State&".
Here's the error I get: "a reference of type 'SimTK::State&' cannot be initialized with a value of type 'SimTK::MultibodySystem' "
I thought that it would be useful to initialize the state after we add the new subsystems to the multibodysystem.
Kenechukwu
- Thomas Uchida
- Posts: 1792
- Joined: Wed May 16, 2012 11:40 am
Re: Measuring Contact Force in Forward Simulation
Ah, sorry; you're right. Is there a reason you want to use the Manager rather than the TimeStepper as in ExampleContactPlayground.cpp? I will try to build your code and investigate in more detail later tonight.
- Thomas Uchida
- Posts: 1792
- Joined: Wed May 16, 2012 11:40 am
Re: Measuring Contact Force in Forward Simulation
You can use a TimeStepper (https://simtk.org/api_docs/simbody/3.5/ ... epper.html) and make a couple small changes:
I'm guessing that you want to model contact between the seat and the driver. If so, it looks like you will need to add a degree of freedom to get meaningful forces from the CompliantContactSubsystem (the pelvis is currently welded to the seat).
Code: Select all
Model& model = Model("my_model.osim");
model.initSystem();
MultibodySystem& system = model.updMultibodySystem();
ContactTrackerSubsystem tracker(system);
CompliantContactSubsystem contactForces(system, tracker);
forceReport* myForceReport = new forceReport(system, contactForces, 0.1);
system.addEventReporter(myForceReport);
const State& state = system.realizeTopology();
SimTK::RungeKuttaMersonIntegrator integrator(model.getSystem());
SimTK::TimeStepper ts(model.getSystem(), integrator);
ts.initialize(state);
ts.stepTo(10.);
- Kenechukwu Mbanisi
- Posts: 51
- Joined: Fri Feb 10, 2017 2:50 pm
Re: Measuring Contact Force in Forward Simulation
Thank you Tom.
With your comments, I was able to have the code compile and run successfully, however, as you noted, the contact observer doesn't measure any active contacts during simulation. I ran the same model in the OpenSim GUI using the forward dynamics and force reporter tools and I was able to observe contact forces through the various contact interfaces in the model (the hip/femur to seat and the foot to ground).
As you stated, there'll be no contact forces from the contact interfaces connected to the pelvis (because its welded to the seat), but we're trying to measure the forces from the other interfaces.
Please see images here: (I had some trouble uploading images directly onto this window)
Full model after 1s of simulation showing the contact forces: https://goo.gl/2iK7fu
Plot of contact force on the femur (force "a"): https://goo.gl/x8mc37
Plot of contact force on the foot (force "b"): https://goo.gl/wH4qVA
I am guessing that my definition of the Compliant Contact Subsystem might be inaccurate because no contact forces or surfaces are being observed.
With your comments, I was able to have the code compile and run successfully, however, as you noted, the contact observer doesn't measure any active contacts during simulation. I ran the same model in the OpenSim GUI using the forward dynamics and force reporter tools and I was able to observe contact forces through the various contact interfaces in the model (the hip/femur to seat and the foot to ground).
As you stated, there'll be no contact forces from the contact interfaces connected to the pelvis (because its welded to the seat), but we're trying to measure the forces from the other interfaces.
Please see images here: (I had some trouble uploading images directly onto this window)
Full model after 1s of simulation showing the contact forces: https://goo.gl/2iK7fu
Plot of contact force on the femur (force "a"): https://goo.gl/x8mc37
Plot of contact force on the foot (force "b"): https://goo.gl/wH4qVA
I am guessing that my definition of the Compliant Contact Subsystem might be inaccurate because no contact forces or surfaces are being observed.