donkeycar
donkeycar copied to clipboard
Suggestion: add support for external plugins capability
As an evolving project, I think it's getting to the point when it's sometimes easier to maintain a standalone plugin instead of trying to contribute to the core of the project:
- Easier to support multiple different hardware setups
- Should be pretty easy to implement based on the current pluggable architecture:
- "Parts" to be packaged as an external modules
- Registered within existing configuration directory (i.e. 'mycar")
- Easier to upgrade the core project without touching the plugins
- Popular plugins can later be added to the core
- Currently it's hard to maintain multiple unmerged contributions.
Comments are welcomed!
I understand the rationale and I am open to this idea. Perhaps we can try this in a hybrid mode? Meaning that we are still doing the same thing for existing parts but also accept new parts as an external module. If you can draft a sample we can discuss and probably build something based on that. What do you think @tawnkramer @tikurahul @DocGarbanzo ?
@cloud-rocket, @sctse999 - this makes perfect sense to me. It requires to simplify the part interface and interaction between parts - I made a mock design of a possible solution some time ago (see here: https://gist.github.com/DocGarbanzo/f80c0ce9a8984d9f5f8e857ffd1cb244). Anyway this would allow to build the car basically from a yaml/json file and wouldn't need a car template any longer. We could easily add support to read user parts from a file in the mycar
directory which then can be added together with the DC library parts without any requirements to change the DC code for supporting new parts. Such parts could be shared between users then.
@sctse999 , @DocGarbanzo, I am not yet fully baked, but how about the following.
- 3rd party parts will be installed as standard Python packages
donkeycar
package will hold the following part_registry.py
file
import pkg_resources
# Import all core parts here
from parts.camera import PiCamera
from parts.imu import IMU
...
PARTS_REGISTRY = {
'picamera': PiCamera,
'imu': IMU,
...
}
for entry_point in pkg_resources.iter_entry_points('donkeycar.parts'):
PARTS_REGISTRY [entry_point.name] = entry_point.resolve()
Customer part (3rd party Python standard package will hold the following in setup.py
(or setup.ini
):
entry_points={
'donkeycar.parts': [
"custom_part = my_library.parts:MyPart"
]
}
mycar
will load the core and 3rd party parts (via installed 3d party modules) based on the registry.
Extra things to consider:
- How to enable/disable certain parts
- Parts order of loading (if template is eliminated)
- 3d party packages can easily be generated with https://pypi.org/project/PyScaffold/
@cloud-rocket - I think this is too complicated for third party parts. We want users to write their own python classes, but we don't need them on pypi. They would just put python modules in their car folder and we would have a generic mechanism to load them.
I understand the underlying sentiment here. @DocGarbanzo has a plan to make it easy to define a vehicle pipeline declaratively that will make integrating new parts very easy, so I am going to close this issue.