Home › Forum › SOFA › Using SOFA › [SOLVED] How to add python script to c++ code
- This topic has 10 replies, 2 voices, and was last updated 7 years, 3 months ago by Yannie.
-
AuthorPosts
-
21 June 2017 at 19:44 #9342YannieBlocked
Hello All,
I’m learning to write scene in C++, and would like to use the python keyboard control script in it, any example code to show how to do this?
I tried to define a PythonScriptController pointer, but when I ran the code, it always show an error:
Unhandled exception at 0x000000001E08BF77 (python27.dll) in test.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Thank you!
23 June 2017 at 17:42 #9348HugoKeymasterHi Yannie,
To use Python scripts in a simulation written in C++, indeed, you need to do is to instantiate the C++ class PythonScriptController. Your C++ application must therefore have a dependency on the SofaPython plugin (explicit in CMakeList.txt).
HTH,Hugo
24 June 2017 at 05:15 #9356YannieBlockedThanks Hugo for the reply.
I did add sofaPython plugin. But it always gives the above error. It looks the the pythonscriptcontroller instance can’t read in the .py file.
Here is my code:
const char* filename = “keyboardControl.py”; sofa::component::controller::PythonScriptController::SPtr pyContr = sofa::core::objectmodel::New<sofa::component::controller::PythonScriptController>(); pyContr->m_filename.setValue(filename);
I suppose the class can parse the .py file automatically once it read in?
24 June 2017 at 15:29 #9357HugoKeymasterHey Yannie,
the error shows that you are using an un-initialized data. But your code looks ok. I would have written :
#include "PythonScriptController.h" ... int main(int argc, char** argv) { ... sofa::simulation::Node::SPtr groot = sofa::simulation::getSimulation()->createNewGraph("root"); groot->setGravity( Coord3(0,-10,0) ); ... std::string filename = "keyboardControl.py"; std::string classname = "yourclassname"; sofa::component::controller::PythonScriptController::SPtr pyContr = sofa::core::objectmodel::New<sofa::component::controller::PythonScriptController>(); pyContr->m_filename.setValue(filename); pyContr->m_classname.setValue(classname); groot->addObject(pyContr); }
and your CMakeLists.txt should look like:
cmake_minimum_required(VERSION 3.1) project(mytest) find_package(SofaSimulation) find_package(SofaPython) add_executable(${PROJECT_NAME} test.cpp) target_link_libraries(${PROJECT_NAME} SofaPython SofaSimulation)
HTH,
Hugo
30 June 2017 at 22:53 #9547YannieBlockedThanks Hugo!
I’ve play around a bit, it still has this problem, I’m able to locate where the error come but not sure how to solve it. So the code run into the python error at this line:sofa::simulation::getSimulation()->init(groot.get());
And I can trace it to PythonScriptController::script_initGraph(Node *node), it gave the exception at here.
Does it has something to do with the m_classname? I assume it should be the classname in Python script. Then I tried to just type some simple code in python, like
def createScene(node): def hello(): print 'hello !'
But still, no luck.
Any thoughts? Thanks!1 July 2017 at 00:25 #9595HugoKeymasterHi Yannie
Could you please post the complete Python script ? Python scripts are sensitive to tabulations. Seeing the entire script would help,
Thank you !
1 July 2017 at 03:22 #9596YannieBlockedThe script I posted above is the whole script. For this script, I didn’t add m_classname as there is no class name in it.
I also tried the PythonScriptController_Placeholders.py in the sofaPython examples folder and set the m_classname to ExampleController, same problem!
Thanks!
10 July 2017 at 14:21 #9782HugoKeymasterHi Yannie,
You tried PythonScriptController_Placeholders.py in your C++ scene and it did not work ?
In your C++ scene, you instantiated a PythonScripController with the data filename set toPythonScriptController_Placeholders.py
and the data classname set to the stringExampleController
?Have you tried to specify in you C++ scene, a RequiredPlugin with the data pluginName set to
SofaPython
?HTH
Hugo
17 July 2017 at 22:17 #9797YannieBlockedThanks Hugo,
Well, I debugged for some time and found that the PythonScripController.cpp constructor doesn’t call loadscript(), so I write add a new constructor and rebuilt sofaPython and it worked. I seems that the PythonScripController was written for use cases that read scene files instead of constructor the object in code, because it does work if I just load the .scn file for runsofa. I could be wrong as I don’t know the platform well enough. Does it work for you if you just assign filename and classname?
Additional question. So I tried the keyboardcontrol.py again, but my object doesn’t move and the error is mechanicalState.free_position index out range. And I print out free_position, it is empty, when and where this free_position is initiated?
Thanks again!
Yannie19 July 2017 at 14:27 #9805HugoKeymasterDear Yannie,
Your question has been discussed at the weekly dev meeting (you can follow the agenda and report by subscribing to the sofa-dev mailing list).
Here is the answer I got:- a question on the forum about SofaPython in a C++ scene: the best is to initialize the python environment using the PluginManager (sofa::helper::system::PluginManager). Thus, you are able to directly load the python environment
- about the initialization of free_position (in the MultiVector of the MechanicalState), it is created when a FreeAnimationLoop is created if I remember properly. Otherwise, it won’t be allocated.
HTH
Best,Hugo
25 July 2017 at 23:34 #9853YannieBlockedThanks Hugo!
I did use the PluginManager to load the SofaPython as well as adding RequiredPlugin node, not sure why it didn’t call loadscript with that setting.
Thanks, the FreeMotionAnimationLoop does help, now I can move object around!
Best,
Yannie -
AuthorPosts
- You must be logged in to reply to this topic.