-
Notifications
You must be signed in to change notification settings - Fork 275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for writing systems in Python #2081
Conversation
} | ||
catch (const pybind11::error_already_set &_err) | ||
{ | ||
gzerr << _err.what() << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will the error message contain the name of the method and python module here? It would certainly help with tracking down errors, otherwise they will all have the same name, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should, but I'll double check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I threw an exception in the python file and this is what I got
[Err] [PythonSystemLoader.cc:174] NameError: name 'entity' is not defined
At:
~/ws/harmonic/src/gz-sim/python/test/plugins/test_model_system.py(51): pre_update
I think that's sufficient.
} | ||
|
||
////////////////////////////////////////////////// | ||
void PythonSystemLoader::PostUpdate(const UpdateInfo &_info, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did we determine what happens when there are multiple python modules? Is that supported/unsupported?
Postupdate is the most interesting case because of parallel execution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, we're currently creating an instance of pybind11::scoped_interpreter
in ServerPrivate
and it seems to work fine with multiple python modules, since there's only one Server
instance. However, if we want to have multiple Server
s in the same process, this will not work. So maybe we need a Singleton for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can generally assume that multiple Servers per process isn't likely at the moment. We may want to add a note somewhere in the event that someone attempts it, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the tests were failing because they initialized two Server
instances. I fixed it by using pybind11::initialize_interpreter()
instead of pybind11::scoped_interpreter
so we can skip initialization of the interpreter is already initialized.
Hmm, approval is more of approval-of-approach. I think we still need a few tests here (which you have already noted) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works for me, this is very cool. I just left very minor comments.
I think the PythonSystemLoader
is a good option. I was thinking if it would make sense to promote this upstream somehow but I didn't find a better approach than this one.
Signed-off-by: Addisu Z. Taddese <[email protected]>
This allows multiple PythonSystemLoaders to run albeit with a single python interpreter. Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There were a couple of GIL issues that showed up when I started using gz-transport inside the python system. The fix requires releasing the GIL when we run PostUpdate
threads and acquire the GIL from the threads each PostUpdate
runs in. This also requires an update to gz-transport so that the GIL is acquired before calling subscription callbacks since that also happens from a different thread than the main thread that contains the Python interpreter.
} | ||
|
||
////////////////////////////////////////////////// | ||
void PythonSystemLoader::PostUpdate(const UpdateInfo &_info, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the tests were failing because they initialized two Server
instances. I fixed it by using pybind11::initialize_interpreter()
instead of pybind11::scoped_interpreter
so we can skip initialization of the interpreter is already initialized.
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
} | ||
|
||
void PythonSystemLoader::Configure( | ||
const Entity &_entity, const std::shared_ptr<const sdf::Element> &_sdf, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
include ENtity, sdf::Element, EntityComponentManager, EventManager, SystemLoader
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some were already there, added the rest in f30128f
CallPythonMethod(this->resetMethod, _info, &_ecm); | ||
} | ||
|
||
GZ_ADD_PLUGIN(PythonSystemLoader, System, ISystemConfigure, ISystemPreUpdate, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
include system.hh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to if it's already in "PythonSystemLoader.hh"? Added anyway f30128f
common::joinPaths(std::string(PROJECT_SOURCE_PATH), "python", | ||
"test", "plugins")); | ||
|
||
sim::ServerConfig serverConfig; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
include: ServerConfig, gz/common/Filesystem.hh, components::Name, components::Model, sim::worldPose
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the headers were already there, added the rest in f30128f
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Signed-off-by: Addisu Z. Taddese <[email protected]>
Codecov Report
@@ Coverage Diff @@
## main #2081 +/- ##
==========================================
- Coverage 65.32% 65.30% -0.03%
==========================================
Files 321 322 +1
Lines 30303 30410 +107
==========================================
+ Hits 19795 19858 +63
- Misses 10508 10552 +44
|
🎉 New feature
Closes #790
Replaces #2045, which was automatically closed by Github when the branch it was targeting was deleted.
Summary
Creates a C++ system that is able to load a python module and pass along the System interface calls, such as
Configure
,PreUpdate
, etc. The convention is pretty simple. The python module exposes aget_system
function which returns an instance of a class that implements the desired System interface functions.I'd appreciate feedback on the convention/general interface between
PythonSystemLoader
and python systems.TODO:
Test it
Run
examples/worlds/python_system_loader.sdf
. See the file for instructions on environmental variables that need to be set.Checklist
codecheck
passed (See contributing)Note to maintainers: Remember to use Squash-Merge and edit the commit message to match the pull request summary while retaining
Signed-off-by
messages.