simulation
- shayan moradkhani
- Posts: 41
- Joined: Fri May 05, 2017 5:12 pm
simulation
hello,
i have created a model as in the attachment. what i want to do is to run a simulation that the ellipsoid touches the two grounds and then, i want to apply a force (increasing over time) at a specific point of the ellipsoid until the ellipsoid starts moving (overcoming friction).
i have created contact geometries between grounds and ellipsoid. i defined contact forces and friction.
for this touching, should i use forward dynamics that the ellipsoid drops with gravity?
or is it possible to control the movement of ellipsoid with the same force which is being applied on a specific point during contact?
how can i find the exact dimension of the ellipsoid?
there is also a .png file attached, which is schematic of the story. i could not attach the ellipsoid_center.obj.
i appreciate your help
regards
Shayan
i have created a model as in the attachment. what i want to do is to run a simulation that the ellipsoid touches the two grounds and then, i want to apply a force (increasing over time) at a specific point of the ellipsoid until the ellipsoid starts moving (overcoming friction).
i have created contact geometries between grounds and ellipsoid. i defined contact forces and friction.
for this touching, should i use forward dynamics that the ellipsoid drops with gravity?
or is it possible to control the movement of ellipsoid with the same force which is being applied on a specific point during contact?
how can i find the exact dimension of the ellipsoid?
there is also a .png file attached, which is schematic of the story. i could not attach the ellipsoid_center.obj.
i appreciate your help
regards
Shayan
- Attachments
-
- Untitled.png (7.75 KiB) Viewed 1554 times
-
- foot1.osim
- (15.6 KiB) Downloaded 103 times
Re: simulation
I made a number of changes to your model. (i) To even get it to run you need to have inertia values for bodies. (ii) The relationship between the body and the geometry was not correct. You put in a translational (and rotational) offset between the body and its geometry, which is incorrect. If you want to place the body in a specific location, you should change the parameters for the joint (location_parent). (iii) I was not able to access an ellipsoid mesh so I replaced it with a sphere. (iv) I didn't get the expected behavior with the elastic foundation force, so I replaced it with the Hunt Crossly type.
Gravity is already acting on the model. You can add your force separately.should i use forward dynamics that the ellipsoid drops with gravity?
or is it possible to control the movement of ellipsoid with the same force which is being applied on a specific point during contact?
Compute the distances between verticeshow can i find the exact dimension of the ellipsoid?
- Attachments
-
- foot1_updated.osim
- (15.44 KiB) Downloaded 179 times
- shayan moradkhani
- Posts: 41
- Joined: Fri May 05, 2017 5:12 pm
Re: simulation
hi,
thank you very much indeed for your help. it takes quite a long time till i get the handle of OpenSim. the current state of my model is now it falls with gravity and hits the ground bodies and fairly raches static equilibrium. my ultimate goal is to tell the system: start the simulation from 1st resting position and see what is maximum force you can tolerate before slip, then start with 2nd resting position and tell your Fmax, then 3rd,.... (the rest position must have contact with both ground bodies)
my resting positions take only x,y, and z letting three rotational coordinates to change with x,y,and z.
for the force i suppose i have to use: "void setPointFunctions (Function *pointX, Function *pointY, Function *pointZ)
Set the functions which specify the point at which to apply the force. More... "
and "void setForceFunctions (Function *forceX, Function *forceY, Function *forceZ)
Set the functions which specify the force to apply. More..."
i suppose those above functions give me the ability to define my force function, point, and direction.
how can i access the velocity of center of mass of my body during simulation? i am trying to design a controller which takes the velocity of center of mass as input, compares it with a limit for the velocity of center of mass (which i define), and if not exceeding the limit, applying a force (as output) and increasing it over time until the body starts to move. as soon as the velocity goes over the limit, simulation needs to be stopped, printing the maximum force.
i read about body kinematics, but it looks like, that the kinematics will be stored somewhere after simulation. what i need is velocity during simulation.
i also found the following codes on "re. getVelocity() function" and i dont really know if it is useful for me:
Vec3 massCenter;Vec3 velocity;
osimModel.getBodySet().get("hand").getMassCenter(massCenter);
osimModel.getMultibodySystem().realize(s, Stage::Velocity);
osimModel.getSimbodyEngine().getVelocity(s,osimModel.getBodySet()
.get("hand"),massCenter, velocity);
at this stage, I want to be able to run this simulation once, then i will try to start simulation with different coordinate values.
in advance i appreciate your help once more
regards
Shayan
thank you very much indeed for your help. it takes quite a long time till i get the handle of OpenSim. the current state of my model is now it falls with gravity and hits the ground bodies and fairly raches static equilibrium. my ultimate goal is to tell the system: start the simulation from 1st resting position and see what is maximum force you can tolerate before slip, then start with 2nd resting position and tell your Fmax, then 3rd,.... (the rest position must have contact with both ground bodies)
my resting positions take only x,y, and z letting three rotational coordinates to change with x,y,and z.
for the force i suppose i have to use: "void setPointFunctions (Function *pointX, Function *pointY, Function *pointZ)
Set the functions which specify the point at which to apply the force. More... "
and "void setForceFunctions (Function *forceX, Function *forceY, Function *forceZ)
Set the functions which specify the force to apply. More..."
i suppose those above functions give me the ability to define my force function, point, and direction.
how can i access the velocity of center of mass of my body during simulation? i am trying to design a controller which takes the velocity of center of mass as input, compares it with a limit for the velocity of center of mass (which i define), and if not exceeding the limit, applying a force (as output) and increasing it over time until the body starts to move. as soon as the velocity goes over the limit, simulation needs to be stopped, printing the maximum force.
i read about body kinematics, but it looks like, that the kinematics will be stored somewhere after simulation. what i need is velocity during simulation.
i also found the following codes on "re. getVelocity() function" and i dont really know if it is useful for me:
Vec3 massCenter;Vec3 velocity;
osimModel.getBodySet().get("hand").getMassCenter(massCenter);
osimModel.getMultibodySystem().realize(s, Stage::Velocity);
osimModel.getSimbodyEngine().getVelocity(s,osimModel.getBodySet()
.get("hand"),massCenter, velocity);
at this stage, I want to be able to run this simulation once, then i will try to start simulation with different coordinate values.
in advance i appreciate your help once more
regards
Shayan
Last edited by shayan moradkhani on Tue Jul 04, 2017 4:44 am, edited 2 times in total.
- shayan moradkhani
- Posts: 41
- Joined: Fri May 05, 2017 5:12 pm
Re: simulation
hi,
following my previous post,if it is not possible to read the velocity of the center of the mass throughout the simulation and feed it to the controller, would it be possible to define a point or a marker on the center of the mass and track it's velocity?
regards
shayan
following my previous post,if it is not possible to read the velocity of the center of the mass throughout the simulation and feed it to the controller, would it be possible to define a point or a marker on the center of the mass and track it's velocity?
regards
shayan
Last edited by shayan moradkhani on Mon Jul 10, 2017 3:30 am, edited 1 time in total.
- shayan moradkhani
- Posts: 41
- Joined: Fri May 05, 2017 5:12 pm
Re: simulation
hi,
is there any possibility to feed in the final states of one simulation as the beginning of another simulation?
for my simulation in my previous posts, i was not able to stop the simulation at a desired state, so i suppose i have to run simulations of very small time periods and start my analysis. my model starts from free falling and hitting the ground bodies and eventually reaching a velocity close enough to zero, then i start applying a force on the model to c when it starts to move.
if somebody has any point on my previous posts, that would be helpful
any help would be appreciated
regards
Shayan
is there any possibility to feed in the final states of one simulation as the beginning of another simulation?
for my simulation in my previous posts, i was not able to stop the simulation at a desired state, so i suppose i have to run simulations of very small time periods and start my analysis. my model starts from free falling and hitting the ground bodies and eventually reaching a velocity close enough to zero, then i start applying a force on the model to c when it starts to move.
if somebody has any point on my previous posts, that would be helpful
any help would be appreciated
regards
Shayan
- shayan moradkhani
- Posts: 41
- Joined: Fri May 05, 2017 5:12 pm
Re: simulation
hello everyone,
i'm stuck in the middle of a c++ code.
according to the attached code, i load the model, and create an event handler using triggeredEventHandler. constructor looks safe, witness function has become a bit too confusing to me; i want my witness function to be the velocity of the center of mass which in case of going over a certain threshold (velocityThreshold) the simulation is terminated by event handler function. my difficulties are how to put the center of mass velocity in witness function, how to get the time when the simulation is terminated (when event has happened), and how to connect my prescribed force (my model has already a prescribed force) to the simulation time?
when i compile the code, i get three errors as attached.
error C1506 refers to the last line 87 where the curly-brace closes the main function.
error regarding pointer type: BodySet &bs = _model->updBodySet(); (i changed -> to . in other places, however, i dont know what will happen)
and Body is ambiguous:Body &aBody = bs.get('foot');
please if anybody has any ideas, it would be very appreciated.
regards
Shayan
i'm stuck in the middle of a c++ code.
according to the attached code, i load the model, and create an event handler using triggeredEventHandler. constructor looks safe, witness function has become a bit too confusing to me; i want my witness function to be the velocity of the center of mass which in case of going over a certain threshold (velocityThreshold) the simulation is terminated by event handler function. my difficulties are how to put the center of mass velocity in witness function, how to get the time when the simulation is terminated (when event has happened), and how to connect my prescribed force (my model has already a prescribed force) to the simulation time?
when i compile the code, i get three errors as attached.
error C1506 refers to the last line 87 where the curly-brace closes the main function.
error regarding pointer type: BodySet &bs = _model->updBodySet(); (i changed -> to . in other places, however, i dont know what will happen)
and Body is ambiguous:Body &aBody = bs.get('foot');
please if anybody has any ideas, it would be very appreciated.
regards
Shayan
- Attachments
-
- termination.cpp
- (3.06 KiB) Downloaded 70 times
-
- error.PNG (6.22 KiB) Viewed 1337 times
- Thomas Uchida
- Posts: 1792
- Joined: Wed May 16, 2012 11:40 am
Re: simulation
The SimTK and OpenSim namespaces both contain a Body class. You could remove one of the using statements (line 3 or line 4), or replace Body with OpenSim::Body on line 45."Body" is ambiguous
- shayan moradkhani
- Posts: 41
- Joined: Fri May 05, 2017 5:12 pm
Re: simulation
hi,
thank you very much for your response. i did what you mentioned, however, i am still getting error C1506: unrecoverable block scoping error.
#include <OpenSim/OpenSim.h>
#include <cmath>
using namespace OpenSim;
using namespace SimTK;
using namespace std;
int main()
{
try {
// Create a new OpenSim model from file
Model osimModel("C:/Users/shayan/Desktop/new/foot1_withPrescribedForce.osim");
double velocityThreshold = 1.0;
double initialTime = 0.0;
double finalTime = 2.0;
//=============================================================================
// EVENT HANDLER: TerminateSimulation
// Triggered when the center of mass velocity falls below some threshold
//=============================================================================
class TerminateSimulation : public SimTK::TriggeredEventHandler {
public:
double velocityThreshold = 1.0;
double settleTime = 0.2;
// CONSTRUCTOR
TerminateSimulation(const Model& m, double threshold) : TriggeredEventHandler(Stage::Velocity),
_model(m), _velocityThreshold(threshold)
{
getTriggerInfo().setTriggerOnFallingSignTransition(true);
}
// WITNESS FUNCTION
SimTK::Real getValue(const SimTK::State& s) const
{
// keep returning a positive value while the contact settles out
double simTime = s.getTime();
if (simTime < settleTime) {
return 100.0;
}
// center of mass velocity
const BodySet& bodySet = _model.getBodySet();
_model.getMultibodySystem().realize(s, SimTK::Stage::Velocity);
SimTK::Vec3 bodyCoMPosBody, bodyCoMVelGround;
const OpenSim::Body& foot = bodySet.get("foot");
foot.getMassCenter(bodyCoMPosBody);
_model.getSimbodyEngine().getVelocity(s, foot, bodyCoMPosBody, bodyCoMVelGround);
double velocity = sqrt(pow(bodyCoMVelGround[1], 2) + pow(bodyCoMVelGround[2], 2) + pow(bodyCoMVelGround[3], 2));
Array<double> force_vector = _model.getForceSet().get("foot").getRecordValues(s);
double force = sqrt(pow(force_vector[1], 2) + pow(force_vector[2], 2) + pow(force_vector[3], 2));
return velocity - _velocityThreshold;
}
// EVENT HANDLER FUNCTION
void handleEvent(SimTK::State& s, SimTK::Real accuracy, bool& terminate) const
{
std::cout << "terminated because velocity passed threshold" << endl; //debug line
//std::cout << "maximum force prior to slip:" << force << endl;
terminate = true;
}
private:
const Model& _model;
double _velocityThreshold;
};
// Initialize the system. initSystem() cannot be used here because adding the event handler
// must be done between buildSystem() and initializeState().
osimModel.buildSystem();
TerminateSimulation *terminate = new TerminateSimulation(osimModel, velocityThreshold);
osimModel.updMultibodySystem().addEventHandler(terminate);
State &osimState = osimModel.initializeState();
// Create the integrator for the simulation.
RungeKuttaMersonIntegrator integrator(osimModel.getMultibodySystem());
integrator.setAccuracy(1.0e-6);
// Create a manager to run the simulation
Manager manager(osimModel, integrator);
// Integrate from initial time to final time and integrate
manager.setInitialTime(initialTime);
manager.setFinalTime(finalTime);
manager.integrate(osimState);
// Save the model
osimModel.print("C:/Users/shayan/Desktop/new/simulation.osim");
}
catch (const std::exception& ex)
{
std::cout << "Exception in toyLeg_example: " << ex.what() << std::endl;
std::cin.get();
return 1;
}
std::cout << "Exiting" << std::endl;
std::cin.get();
return 0;
}
regards
Shayan
thank you very much for your response. i did what you mentioned, however, i am still getting error C1506: unrecoverable block scoping error.
#include <OpenSim/OpenSim.h>
#include <cmath>
using namespace OpenSim;
using namespace SimTK;
using namespace std;
int main()
{
try {
// Create a new OpenSim model from file
Model osimModel("C:/Users/shayan/Desktop/new/foot1_withPrescribedForce.osim");
double velocityThreshold = 1.0;
double initialTime = 0.0;
double finalTime = 2.0;
//=============================================================================
// EVENT HANDLER: TerminateSimulation
// Triggered when the center of mass velocity falls below some threshold
//=============================================================================
class TerminateSimulation : public SimTK::TriggeredEventHandler {
public:
double velocityThreshold = 1.0;
double settleTime = 0.2;
// CONSTRUCTOR
TerminateSimulation(const Model& m, double threshold) : TriggeredEventHandler(Stage::Velocity),
_model(m), _velocityThreshold(threshold)
{
getTriggerInfo().setTriggerOnFallingSignTransition(true);
}
// WITNESS FUNCTION
SimTK::Real getValue(const SimTK::State& s) const
{
// keep returning a positive value while the contact settles out
double simTime = s.getTime();
if (simTime < settleTime) {
return 100.0;
}
// center of mass velocity
const BodySet& bodySet = _model.getBodySet();
_model.getMultibodySystem().realize(s, SimTK::Stage::Velocity);
SimTK::Vec3 bodyCoMPosBody, bodyCoMVelGround;
const OpenSim::Body& foot = bodySet.get("foot");
foot.getMassCenter(bodyCoMPosBody);
_model.getSimbodyEngine().getVelocity(s, foot, bodyCoMPosBody, bodyCoMVelGround);
double velocity = sqrt(pow(bodyCoMVelGround[1], 2) + pow(bodyCoMVelGround[2], 2) + pow(bodyCoMVelGround[3], 2));
Array<double> force_vector = _model.getForceSet().get("foot").getRecordValues(s);
double force = sqrt(pow(force_vector[1], 2) + pow(force_vector[2], 2) + pow(force_vector[3], 2));
return velocity - _velocityThreshold;
}
// EVENT HANDLER FUNCTION
void handleEvent(SimTK::State& s, SimTK::Real accuracy, bool& terminate) const
{
std::cout << "terminated because velocity passed threshold" << endl; //debug line
//std::cout << "maximum force prior to slip:" << force << endl;
terminate = true;
}
private:
const Model& _model;
double _velocityThreshold;
};
// Initialize the system. initSystem() cannot be used here because adding the event handler
// must be done between buildSystem() and initializeState().
osimModel.buildSystem();
TerminateSimulation *terminate = new TerminateSimulation(osimModel, velocityThreshold);
osimModel.updMultibodySystem().addEventHandler(terminate);
State &osimState = osimModel.initializeState();
// Create the integrator for the simulation.
RungeKuttaMersonIntegrator integrator(osimModel.getMultibodySystem());
integrator.setAccuracy(1.0e-6);
// Create a manager to run the simulation
Manager manager(osimModel, integrator);
// Integrate from initial time to final time and integrate
manager.setInitialTime(initialTime);
manager.setFinalTime(finalTime);
manager.integrate(osimState);
// Save the model
osimModel.print("C:/Users/shayan/Desktop/new/simulation.osim");
}
catch (const std::exception& ex)
{
std::cout << "Exception in toyLeg_example: " << ex.what() << std::endl;
std::cin.get();
return 1;
}
std::cout << "Exiting" << std::endl;
std::cin.get();
return 0;
}
regards
Shayan
- Thomas Uchida
- Posts: 1792
- Joined: Wed May 16, 2012 11:40 am
Re: simulation
This is a C++ issue, not an OpenSim issue. You can find many resources online by Googling "c++ c1506". I didn't investigate thoroughly, but I suggest trying with the TerminateSimulation class defined outside (above) main().i did what you mentioned, however, i am still getting error C1506: unrecoverable block scoping error.
- shayan moradkhani
- Posts: 6
- Joined: Mon Apr 24, 2017 4:53 am
Re: simulation
hi,
i really appreciate your response. here is my code. it builds fine but when i open the .exe file it says program stopped working.
#include <OpenSim/OpenSim.h>
#include <cmath>
using namespace OpenSim;
using namespace SimTK;
using namespace std;
//=============================================================================
// EVENT HANDLER: TerminateSimulation
// Triggered when the center of mass velocity falls below some threshold
//=============================================================================
class TerminateSimulation : public SimTK::TriggeredEventHandler {
public:
double settleTime = 0.2;
// CONSTRUCTOR
TerminateSimulation(const Model& m, double threshold) : TriggeredEventHandler(Stage::Velocity),
_model(m), _velocityThreshold(threshold)
{
getTriggerInfo().setTriggerOnFallingSignTransition(true);
}
// WITNESS FUNCTION
SimTK::Real getValue(const SimTK::State& s) const
{
// keep returning a positive value while the contact settles out
double simTime = s.getTime();
if (simTime < settleTime) {
return 100.0;
}
// center of mass velocity
const BodySet& bodySet = _model.getBodySet();
_model.getMultibodySystem().realize(s, SimTK::Stage::Velocity);
SimTK::Vec3 bodyCoMPosBody, bodyCoMVelGround;
const OpenSim::Body& foot = bodySet.get("foot");
foot.getMassCenter(bodyCoMPosBody);
_model.getSimbodyEngine().getVelocity(s, foot, bodyCoMPosBody, bodyCoMVelGround);
double velocity = sqrt(pow(bodyCoMVelGround[1], 2) + pow(bodyCoMVelGround[2], 2) + pow(bodyCoMVelGround[3], 2));
Array<double> force_vector = _model.getForceSet().get("foot").getRecordValues(s);
double force = sqrt(pow(force_vector[1], 2) + pow(force_vector[2], 2) + pow(force_vector[3], 2));
return velocity - _velocityThreshold;
}
// EVENT HANDLER FUNCTION
void handleEvent(SimTK::State& s, SimTK::Real accuracy, bool& terminate) const
{
std::cout << "terminated because velocity passed threshold" << endl; //debug line
//std::cout << "maximum force prior to slip:" << force << endl;
terminate = true;
}
private:
const Model& _model;
double _velocityThreshold;
};
int main()
{
try {
// Create a new OpenSim model from file
Model osimModel("C:/Users/shayan/Desktop/static model/foot1.osim");
double initialTime = 0.0;
double finalTime = 2.0;
// Initialize the system. initSystem() cannot be used here because adding the event handler
// must be done between buildSystem() and initializeState().
osimModel.buildSystem();
double velocityThreshold = 0.2;
TerminateSimulation *terminate = new TerminateSimulation(osimModel, velocityThreshold);
osimModel.updMultibodySystem().addEventHandler(terminate);
State &osimState = osimModel.initializeState();
// Create the integrator for the simulation.
RungeKuttaMersonIntegrator integrator(osimModel.getMultibodySystem());
integrator.setAccuracy(1.0e-6);
// Create a manager to run the simulation
Manager manager(osimModel, integrator);
// Integrate from initial time to final time and integrate
manager.setInitialTime(initialTime);
manager.setFinalTime(finalTime);
manager.integrate(osimState);
// Save the model
osimModel.print("C:/Users/shayan/Desktop/static model/foot1static.osim");
}
catch (const std::exception& ex)
{
std::cout << "Exception in toyLeg_example: " << ex.what() << std::endl;
std::cin.get();
return 1;
}
std::cout << "Exiting" << std::endl;
std::cin.get();
return 0;
}
i am really new to programming, therefore accept my apology for my incompetence.
regards
Shayan
i really appreciate your response. here is my code. it builds fine but when i open the .exe file it says program stopped working.
#include <OpenSim/OpenSim.h>
#include <cmath>
using namespace OpenSim;
using namespace SimTK;
using namespace std;
//=============================================================================
// EVENT HANDLER: TerminateSimulation
// Triggered when the center of mass velocity falls below some threshold
//=============================================================================
class TerminateSimulation : public SimTK::TriggeredEventHandler {
public:
double settleTime = 0.2;
// CONSTRUCTOR
TerminateSimulation(const Model& m, double threshold) : TriggeredEventHandler(Stage::Velocity),
_model(m), _velocityThreshold(threshold)
{
getTriggerInfo().setTriggerOnFallingSignTransition(true);
}
// WITNESS FUNCTION
SimTK::Real getValue(const SimTK::State& s) const
{
// keep returning a positive value while the contact settles out
double simTime = s.getTime();
if (simTime < settleTime) {
return 100.0;
}
// center of mass velocity
const BodySet& bodySet = _model.getBodySet();
_model.getMultibodySystem().realize(s, SimTK::Stage::Velocity);
SimTK::Vec3 bodyCoMPosBody, bodyCoMVelGround;
const OpenSim::Body& foot = bodySet.get("foot");
foot.getMassCenter(bodyCoMPosBody);
_model.getSimbodyEngine().getVelocity(s, foot, bodyCoMPosBody, bodyCoMVelGround);
double velocity = sqrt(pow(bodyCoMVelGround[1], 2) + pow(bodyCoMVelGround[2], 2) + pow(bodyCoMVelGround[3], 2));
Array<double> force_vector = _model.getForceSet().get("foot").getRecordValues(s);
double force = sqrt(pow(force_vector[1], 2) + pow(force_vector[2], 2) + pow(force_vector[3], 2));
return velocity - _velocityThreshold;
}
// EVENT HANDLER FUNCTION
void handleEvent(SimTK::State& s, SimTK::Real accuracy, bool& terminate) const
{
std::cout << "terminated because velocity passed threshold" << endl; //debug line
//std::cout << "maximum force prior to slip:" << force << endl;
terminate = true;
}
private:
const Model& _model;
double _velocityThreshold;
};
int main()
{
try {
// Create a new OpenSim model from file
Model osimModel("C:/Users/shayan/Desktop/static model/foot1.osim");
double initialTime = 0.0;
double finalTime = 2.0;
// Initialize the system. initSystem() cannot be used here because adding the event handler
// must be done between buildSystem() and initializeState().
osimModel.buildSystem();
double velocityThreshold = 0.2;
TerminateSimulation *terminate = new TerminateSimulation(osimModel, velocityThreshold);
osimModel.updMultibodySystem().addEventHandler(terminate);
State &osimState = osimModel.initializeState();
// Create the integrator for the simulation.
RungeKuttaMersonIntegrator integrator(osimModel.getMultibodySystem());
integrator.setAccuracy(1.0e-6);
// Create a manager to run the simulation
Manager manager(osimModel, integrator);
// Integrate from initial time to final time and integrate
manager.setInitialTime(initialTime);
manager.setFinalTime(finalTime);
manager.integrate(osimState);
// Save the model
osimModel.print("C:/Users/shayan/Desktop/static model/foot1static.osim");
}
catch (const std::exception& ex)
{
std::cout << "Exception in toyLeg_example: " << ex.what() << std::endl;
std::cin.get();
return 1;
}
std::cout << "Exiting" << std::endl;
std::cin.get();
return 0;
}
i am really new to programming, therefore accept my apology for my incompetence.
regards
Shayan