How to register new Controller class type written in OpenSim API

Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
User avatar
Kenechukwu Mbanisi
Posts: 51
Joined: Fri Feb 10, 2017 2:50 pm

How to register new Controller class type written in OpenSim API

Post by Kenechukwu Mbanisi » Mon Jun 19, 2017 4:09 pm

Hello there,

I developed a controller (following the ControllerExample) and I was able to run a forward simulation using the OpenSim API.

Now, I would like to add this controller to my model and then run in either in the OpenSim GUI or using the MATLAB API.

When I try to open the model in the OpenSim GUI, it opens, but without the controller attached. Here's the error that comes up (I named my controller object "PDController"):

Code: Select all

Object::newInstanceOfType(): object type 'PDController' is not a registered Object!
Object type PDController not recognized
Apparently, I need to get this new controller class type registered with OpenSim or so to be able to access it here. Can I please get some guidance on what I need to do to get this done?

Thank you.

Kenechukwu

User avatar
Christopher Dembia
Posts: 506
Joined: Fri Oct 12, 2012 4:09 pm

Re: How to register new Controller class type written in OpenSim API

Post by Christopher Dembia » Mon Jun 19, 2017 9:35 pm

Look at one of the Plugin examples (like AnalysisPluginExample). You will need to ensure that

Code: Select all

OpenSim::RegisterType(PDController());
is called when your plugin is loaded.

User avatar
Kenechukwu Mbanisi
Posts: 51
Joined: Fri Feb 10, 2017 2:50 pm

Re: How to register new Controller class type written in OpenSim API

Post by Kenechukwu Mbanisi » Tue Jun 20, 2017 8:29 pm

Hello Christopher,

Thanks for your response here.

My initial approach was basically following the ControllerExample where I write a new class (PDController) based on the Controller class as part of my main program. Then I add the controller to the model using these calls:

Code: Select all

PDController *controller = new PDController(kp, kv);
controller->setActuators(osimModel.updActuators());
osimModel.addController(controller);
I didn't need to write a separate plug-in as in the AnalysisPluginExample. This compiled and ran properly like I said, but the controller was not 'registered' when I tried to open up the model in the OpenSim GUI.

I tried several things after reading your response:

1) Added this function to my main program:

Code: Select all

OpenSim::Object::registerType(PDController(kp, kv));
Result: This compiled and ran properly, but when I loaded the model (which has the controller included), it showed the same error as the first time. Am I doing something wrong here with this approach?

2) I went through the AnalysisPluginExample as you suggested and implemented it correctly. Then I edited the existing template .cpp and .h files to fit my PDController class. When I ran this, it didn't build successfully. Here's the error:

Code: Select all

Creating library C:/Users/Kenechukwu/Documents/PC Files/OpenSim/OpenSimWorkspace/PDController_Plugin-build/RelWithDebInfo/PDControl.lib and object C:/Users/Kenechukwu/Documents/PC Files/OpenSim/OpenSimWorkspace/PDController_Plugin-build/RelWithDebInfo/PDControl.exp

1>PDController.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl OpenSim::Controller::Controller(class OpenSim::Controller &&)" (__imp_??0Controller@OpenSim@@QEAA@$$QEAV01@@Z) referenced in function "public: __cdecl OpenSim::PDController::PDController(class OpenSim::PDController &&)" (??0PDController@OpenSim@@QEAA@$$QEAV01@@Z)

1>RegisterTypes_osimPlugin.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __cdecl OpenSim::Controller::Controller(class OpenSim::Controller &&)" (__imp_??0Controller@OpenSim@@QEAA@$$QEAV01@@Z)

1>PDController.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class OpenSim::Controller & __cdecl OpenSim::Controller::operator=(class OpenSim::Controller &&)" (__imp_??4Controller@OpenSim@@QEAAAEAV01@$$QEAV01@@Z) referenced in function "public: class OpenSim::PDController & __cdecl OpenSim::PDController::operator=(class OpenSim::PDController &&)" (??4PDController@OpenSim@@QEAAAEAV01@$$QEAV01@@Z)

1>RegisterTypes_osimPlugin.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: class OpenSim::Controller & __cdecl OpenSim::Controller::operator=(class OpenSim::Controller &&)" (__imp_??4Controller@OpenSim@@QEAAAEAV01@$$QEAV01@@Z)

1>C:\Users\Kenechukwu\Documents\PC Files\OpenSim\OpenSimWorkspace\PDController_Plugin-build\RelWithDebInfo\PDControl.dll : fatal error LNK1120: 2 unresolved externals
I am not sure what the problem is with approach #2 and why it is not building. Is my approach here valid for what I want to achieve? Can you help me make sense of this error and what to possible rectify?

My Goal: Write a custom controller (like the ControllerExample) and register it to OpenSim so I can perform forward simulation with the model (with controller included) in OpenSim GUI and/or MATLAB API.

Thank you so much. I really appreciate your support here.

Kenechukwu

User avatar
Christopher Dembia
Posts: 506
Joined: Fri Oct 12, 2012 4:09 pm

Re: How to register new Controller class type written in OpenSim API

Post by Christopher Dembia » Tue Jun 20, 2017 11:30 pm

OpenSim::Object::registerType(PDController(kp, kv));
The convention is that you pass in a default-constructed object; that is, one without the "kp" and "kv" values.
Am I doing something wrong here with this approach?
What you did is good if you want to be able to read a model file in your main program, but not for reading the model in other places (the OpenSim GUI or MATLAB). These other places will not have run "registerType()" for your class.
My Goal: Write a custom controller (like the ControllerExample) and register it to OpenSim so I can perform forward simulation with the model (with controller included) in OpenSim GUI and/or MATLAB API.
This is possible. You will need to create a plugin that calls `OpenSim::RegisterType()` for your class when the plugin is loaded, as is done in the Analysis example. You will be able to use your controller in the OpenSim GUI, and through MATLAB (though you will not be able to access your controller directly in MATLAB, because it will not be wrapped via SWIG).
Can you help me make sense of this error and what to possible rectify?
I think we have seen this error when using a version of visual studio that is different from the one with which OpenSim was built. Which version of Visual Studio are you using, and what is the contents of the "buildinfo.txt" file in your OpenSim installation?

User avatar
Kenechukwu Mbanisi
Posts: 51
Joined: Fri Feb 10, 2017 2:50 pm

Re: How to register new Controller class type written in OpenSim API

Post by Kenechukwu Mbanisi » Wed Jun 21, 2017 7:30 am

Hello Christopher,

Thank you so much for your very helpful feedback.

So based on your comments, it's apparent that what I really need to do is create this plugin. I need help figuring out how resolve whatever is causing the error while I am building it.

My Visual Studio Version: 14.0.25431.01
Compiler: Visual Studio 14 Win64

OpenSim Buildinfo:
Compiler: Visual Studio 13 Win64-MSVC

There's apparently a mismatch, but I am curious to know how come I was able to create the AnalysisPlugin example properly and load it in the OpenSim GUI using the same compiler/setup.

Any thoughts on this, please?

Thank you very much.

Kenechukwu

User avatar
Christopher Dembia
Posts: 506
Joined: Fri Oct 12, 2012 4:09 pm

Re: How to register new Controller class type written in OpenSim API

Post by Christopher Dembia » Wed Jun 21, 2017 11:06 am

Any thoughts on this, please?
I don't have a good answer for this. The compatibility between different versions of the MSVC compiler might be hit-or-miss. I believe that at a recent OpenSim workshop, we encountered the issue you showed, and we were able to fix it by using the same compiler version. I was surprised that this was the issue/fix.

Note that installing older versions of Visual Studio on top of newer versions can cause problems. Instead, it might be easier to use a version of OpenSim built with Visual Studio 14 (2015). If you email me, I can send you such a version.

User avatar
Kenechukwu Mbanisi
Posts: 51
Joined: Fri Feb 10, 2017 2:50 pm

Re: How to register new Controller class type written in OpenSim API

Post by Kenechukwu Mbanisi » Wed Jun 21, 2017 12:44 pm

Hey Christopher,

Thanks for the insight on this. I emailed you.

Kenechukwu

User avatar
Kenechukwu Mbanisi
Posts: 51
Joined: Fri Feb 10, 2017 2:50 pm

Re: How to register new Controller class type written in OpenSim API

Post by Kenechukwu Mbanisi » Thu Jun 22, 2017 6:15 pm

Hello Christopher,

I installed the right version of OpenSim (as you recommended) and I was able to build and create the plugin successfully.

Thank you so much for your support here, I really appreciate it. Great work with OpenSim!!!

Best regards,

Kenechukwu

User avatar
Kenechukwu Mbanisi
Posts: 51
Joined: Fri Feb 10, 2017 2:50 pm

Re: How to register new Controller class type written in OpenSim API

Post by Kenechukwu Mbanisi » Thu Jun 22, 2017 7:14 pm

Hey Christopher,

One more thing, I am having little trouble getting the plugin registered on MATLAB.

Here're are the steps I've taken:

1) Add plugin directory to MATLAB path

Code: Select all

edit librarypath.txt
2) Load plugin to MATLAB

Code: Select all

fullpathToDll = 'C:\OpenSim 3.3\plugins\PDControl.dll';
osimModel.LoadOpenSimLibrary(fullpathToDll);
3) Define a controller

Code: Select all

control = PDController();
I get an error saying "undefined function or variable" as if it does no exist.

Am I missing something here?

Thanks.

Kenechukwu
Last edited by Kenechukwu Mbanisi on Fri Jun 23, 2017 9:31 am, edited 1 time in total.

User avatar
Thomas Uchida
Posts: 1780
Joined: Wed May 16, 2012 11:40 am

Re: How to register new Controller class type written in OpenSim API

Post by Thomas Uchida » Fri Jun 23, 2017 1:53 am

I get an error saying "undefined function and variable" as if it does no exist.
There's a comment in the source code (in LoadOpenSimLibrary.h from line 43: https://github.com/opensim-org/opensim- ... rary.h#L43):

Load an OpenSim (plugin) library, using a path to a library (relative or
absolute) but *without* the file extension (.dll, .so, .dylib).

To load a plugin in MATLAB, use the following:
import org.opensim.modeling.*;
opensimCommon.LoadOpenSimLibrary('<path>/osimMyPlugin');

Not sure whether the comment applies only to 4.0, but it would be easy to try removing ".dll" from your "fullpathToDll" variable.

POST REPLY