Page 1 of 1

Access violation adding Controller

Posted: Sat Dec 17, 2016 12:38 pm
by mariakrgrg
Hello,
I am creating my first Controller to my model before doing a Forward Simulation like this:

Code: Select all

	OpenSim::Model model("../mymodel.osim");

	PrescribedController* controller = new PrescribedController();
	controller->setName( "my_controller");
	controller->setActuators( model.getActuators());
	
	double control_time[2] = {0, 0.5}; // time nodes for linear function
	double control_acts[2] = {0.1, 1.0}; // force values at t1 and t2
	PiecewiseLinearFunction *control_func = new PiecewiseLinearFunction( 2, control_time, control_acts);
	control_func->setName( "lin_control_func");
		
	controller->prescribeControlForActuator(  "bifemlh_r", control_func);

	model.addController( controller);

	SimTK::State& si = model.initSystem();
	
	// Add reporters
    ForceReporter* forceReporter = new ForceReporter(&model);
    model.addAnalysis(forceReporter);

	// Create the integrator and manager for the simulation.
	SimTK::RungeKuttaMersonIntegrator integrator(model.getMultibodySystem());
	Manager manager(model, integrator);

	// Define the initial and final simulation times
	double initialTime = 0;
	double finalTime = 0.5;

	// Integrate from initial time to final time
	manager.setInitialTime(initialTime);
	manager.setFinalTime(finalTime);
	manager.integrate(si);
and I am getting this Unhandled Exception:

Code: Select all

Unhandled exception at 0x598bb3e3 in Mysim.exe: 0xC0000005: Access violation reading location 0xbaadf00d.
Has anyone any ideas on what is wrong?

The exception triggers when I am adding the controller (when line "model.addController( controller);" is added).

Re: Access violation adding Controller

Posted: Sat Dec 17, 2016 3:43 pm
by tkuchida
There is a test case that demonstrates adding a PrescribedController to a Model in testControllers.cpp (see testPrescribedControllerOnBlock()): https://github.com/opensim-org/opensim- ... s.cpp#L212

Re: Access violation adding Controller

Posted: Sun Dec 18, 2016 4:55 am
by mariakrgrg
I did it like the example and still the same exception :|

Code: Select all

	// set controller
	PrescribedController controller;
	controller.setName( "my_controller");
	controller.setActuators( model.updActuators());
	controller.prescribeControlForActuator( 0, new Constant( 100));
	controller.setDisabled(false);
	model.addController( &controller);

	model.print("myModelWithController.osim");
    Model modelfileFromFile("myModelWithController.osim");

    // Verify that serialization and then deserialization is correct
	ASSERT(model == modelfileFromFile);

	SimTK::State& si = model.initSystem();
	
	// Create the integrator and manager for the simulation.
	SimTK::RungeKuttaMersonIntegrator integrator(model.getMultibodySystem());
	integrator.setAccuracy(1.0e-3);
	Manager manager(model, integrator);

	// Define the initial and final simulation times
	double initialTime = 0;
	double finalTime = 0.5;

	// Integrate from initial time to final time
	manager.setInitialTime(initialTime);
	manager.setFinalTime(finalTime);
	manager.integrate(si);

Re: Access violation adding Controller

Posted: Sun Dec 18, 2016 4:28 pm
by tkuchida
Which version of OpenSim are you using? You might try adding model.buildSystem() (or model.initSystem()) immediately after loading the model. Model::addController() may be expecting to find internal data structures that haven't been built.

Re: Access violation adding Controller

Posted: Tue Dec 20, 2016 3:39 am
by mariakrgrg
I seem to solve this issue by adding a control function (even a zero-function) to the whole actuator set that was given to controller. Like this:

Code: Select all

	Constant* ccf = new Constant(1);

	string muscle_name;
	for (int i=0; i<model.getActuators().getSize(); i++)
	{
		muscle_name = model.getActuators().get(i).getName();
		if ( muscle_name == "bifemlh_r" || muscle_name == "bifemsh_r" || muscle_name == "grac_r" \
			|| muscle_name == "lat_gas_r" || muscle_name == "med_gas_r" || muscle_name == "sar_r" \
			|| muscle_name == "semimem_r" || muscle_name == "semiten_r")
			controller.prescribeControlForActuator( i, ccf);
		else 
			controller.prescribeControlForActuator( i, new Constant(0));
	}
And now I have a similar exception, but this time after the integration is completed:

Code: Select all

Unhandled exception at 0x06686468 in ACLsim.exe: 0xC0000005: Access violation.
tkuchida wrote:Which version of OpenSim are you using? You might try adding model.buildSystem() (or model.initSystem()) immediately after loading the model. Model::addController() may be expecting to find internal data structures that haven't been built.
I use OpenSim 3.2 and tried your advice but nothing changed :/

Re: Access violation adding Controller

Posted: Tue Dec 20, 2016 10:57 am
by mariakrgrg
I finally solved this by creating the Controller with a pointer to the object and also creating different instances of Control Functions before assing them to the controller.
Like this:

Code: Select all

        // set controller
	PrescribedController* controller = new PrescribedController();
	controller->setName( "flexion_controller");
	controller->setActuators( model.updActuators());
	string muscle_name;
	for (int i=0; i<model.getActuators().getSize(); i++)
	{
		muscle_name = model.getActuators().get(i).getName();
		if ( muscle_name == "bifemlh_r" || muscle_name == "bifemsh_r" || muscle_name == "grac_r" \
			|| muscle_name == "lat_gas_r" || muscle_name == "med_gas_r" || muscle_name == "sar_r" \
			|| muscle_name == "semimem_r" || muscle_name == "semiten_r")
		{
			Constant* ccf = new Constant(1);
			controller->prescribeControlForActuator( i, ccf);
		}
		else 
		{
			Constant* zccf = new Constant(0);
			controller->prescribeControlForActuator( i, zccf);
		}
	}
	controller->setDisabled(false);
	model.addController( controller);

Re: Access violation adding Controller

Posted: Wed Dec 21, 2016 2:52 am
by tkuchida
Thanks for the update. Great that you got it working. I now see that your model has multiple muscles. If you wish to control only a few muscles in the model, you probably want to configure the controller so that it provides controls for only those muscles (using addActuator() rather than setActuators()). You could then use different controllers for different subsets of muscles, for example. Please see the example here: https://github.com/opensim-org/opensim- ... e.cpp#L775.