Skip to content

Using extensions

Extensions are the way to extend the Incar Skill System with custom functionality. Extensions are basically a python package that contains one or more subclasses of e.g. camera integrations, data processing steps, or model architectures. A customized version of draccus is used to be able to select these extensions during system usage.

Installing an extension

Extensions can be installed with pip:

# ensure that your python venv is sourced
pip install [package]               # package can also be a git url
pip install -e [path_to_package]    # editable install allows for hot-reloading code
# ensure that your python venv is sourced
pip install [package]               # package can also be a git url
pip install -e [path_to_package]    # editable install allows for hot-reloading code

Creating an extension

1. Create a package using the following command:

# ensure that your python venv is sourced
incar create_pkg --name [package_name] [--ai] [--cameras] [--processing] [path]
# ensure that your python venv is sourced
incar create_pkg --name [package_name] [--ai] [--cameras] [--processing] [path]

Ensure that the package name is unique to avoid conflicts with other extensions. path is the location where the extension will be created. The --ai, --cameras, --processing flags determine which templates to add for quickly getting started. You can enter multiple of these flags. For a more thorough overview of these templates, check the ai, cameras and processing pages.

2. Observe the subfolders that are created for ai extensions, camera extensions, and data processing extensions. In the __init__.py files in these subfolders, ensure that you import all classes that are wrapped in a draccus subclass-selector. For example, if you have the following camera extension (which is the result of the custom camera tutorial):

my_extension.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from incar.cameras import Camera, CameraConfig
from dataclasses import dataclass

@CameraConfig.register_subclass("oak1")
@dataclass
class Oak1Config(CameraConfig):
    device_id: str = ""
    fps: int = 30

    def build_camera(self) -> "Oak1Camera":
        return Oak1Camera(self) 

class Oak1Camera(Camera):
    def __init__(self, conf: Oak1Config): ...

    def next_frame(self) -> np.ndarray: ...

then make sure your [pkg_name]_cameras/__init__.py includes the line from .my_extension import Oak1Config. The template makes sure of this, but remember it in case you change the class name.

3. Your extension is now complete and ready to be installed!

Hot reloading

If your package is in active development, you can install it in editable mode to allow for hot-reloading. Whenever you save file changes, the Incar Skill System will reload the workspace with the updated code.

Hot reloading has a couple limitations:

  • Newly created/installed packages require a restart of the system.
  • Renaming classes wrapped in a @[BaseClass].register_subclass() require a restart of the system.
  • Camera views may need to be closed and opened for the video stream to continue after hot-reloading, depending on your system.
  • Any loaded or running policies will be unloaded.