Create new component

You can specify and create customized components (drivers and algorithms) for use in Nimbus. This procedure requires:

  • Building a Docker image of the component and uploading it to the user’s repository on Docker Hub

  • Creating a JSON definition file for the Nimbus component

  • Uploading the JSON definition file (and optionally, a visual of the component) to Nimbus

Componet docker container

A Dockerfile is a text-based list of commands for building a Docker container image of the native application code.

  1. In your working directory, create a file named Dockerfile (without any file extension).

  2. With a text editor, include these required parameters in the Dockerfile: - FROM: The directory path to the component’s application code and dependencies - COPY: The source and destination directories for copying into the Docker image - RUN: A sequence of compile/build commands - CMD: Commands to run the application within the Docker container

An example Dockerfile structure, used by Nimbus, is shown below:

 1FROM ros:melodic
 2COPY ./cogniteam_exploration cogniteam_exploration_ws/src/cogniteam_exploration
 3COPY entrypoint.sh /entrypoint.sh
 4RUN chmod +x /entrypoint.sh
 5ENTRYPOINT [ "/entrypoint.sh" ]
 6RUN apt-get update && apt-get install ros-melodic-angles -y && \
 7    apt-get install ros-melodic-image-geometry -y && \
 8    apt-get install ros-melodic-tf2 -y  && apt-get install ros-melodic-tf -y && \
 9    apt-get install ros-melodic-image-transport-plugins -y && \
10    apt-get install ros-melodic-image-transport -y && \
11    apt-get install ros-melodic-move-base-msgs -y && \
12    apt-get install ros-melodic-actionlib-msgs && \
13    apt-get install ros-melodic-cv-bridge -y && rm /var/lib/apt/lists/* -rf
14WORKDIR /cogniteam_exploration_ws/
15RUN . /opt/ros/melodic/setup.sh && catkin_make
16CMD  roslaunch exploration exploration.launch --screen

Refer to here for more details on how to construct a Dockerfile.

  1. From a terminal, enter the following commands to build the Docker image:

1cd path_of_Dockerfile
2docker buildx create --name <nameOfDockerImage>
3docker buildx use <nameOfDockerImage>
4docker run --privileged --rm tonistiigi/binfmt --install all
5docker buildx inspect --bootstrap
  1. From a terminal, log in to your Docker Hub repository with the following command:

1sudo docker login
  1. To push the Docker image to your Docker Hub repository, from a terminal, enter the following command:

1sudo docker buildx build --platform linux/arm64,linux/amd64 -t <nameOfDockerHubRepository>/nameOfDockerImage --push .

Component JSON file

After creating a Docker image for the new component and uploading it to Docker Hub, running the component within Nimbus requires a JSON file containing a definition of the component’s parameters. An annotated template for a typical component definition JSON file is provided below. This example JSON file can be easily modified and renamed for use in your Nimbus projects.

Note

When adapting this template for use in your application, please ensure to delete all comment fields. Only valid JSON parameter:value pairs should remain

  1{
  2   "name": "nimbus/hector",           ### Required, Component name
  3   "className": "Ros1Component",      ### Required, Component class, inputs: "Ros1Component"/"Ros2Component"
  4   "description": "2D laser scan mapping using Hector mapping algorithm",
  5   "start": "START_MODE_AUTO",        ### Optional, defines if the component will load automatically("START_MODE_AUTO") or manualy("START_MODE_MANUAL")
  6   "environment": {                   ### When using Docker, "environment" represents the Docker image of the component
  7      "dockerInfo":
  8      {
  9         "image": "hector1:latest",    ### Sets the repository name and image name inside Docker hub
 10         "commands": [                 ### Used to pass parameters to the component Docker container when it is launched
 11            "roslaunch",
 12            "hector_mapping",
 13            "hector_mapping.launch",
 14            "map_resolution:=${map_resolution}",
 15            "map_size:=${map_size}",
 16            "base_frame:=${base_frame}"
 17         ],
 18         "privileged": true,             ### Allows Docker permission to read and write to all devices on the robot computer.
 19         "gpu": false,                   ### Allows Docker acccess to the the device's GPU
 20         "networkHost": false,           ### Allows Docker access to host's networking namespace
 21         "binds": [                      ### Can be used to bind directory/device on the host machine to the Docker container
 22                     {
 23                        "source": "/dev/video0",     ### Location of the device/folder at the host
 24                        "target": "/dev/video0"      ### Target location at the Docker container
 25                     }
 26         ]
 27      }
 28   },
 29   "parameters": {                    ### Parameters passed to the launch file (replaces params defined with ${} in the command section )
 30      "parameters": [
 31      {
 32         "name": "map_resolution",    ### Parameter name. Must be the same as in the "commands" section, above
 33         "description": "",           ### Optional
 34         "doubleValue": 0.1           ### Parameter data type
 35      },
 36      {
 37         "name": "map_string",
 38         "description": "",
 39         "stringValue": "string-value"
 40      },
 41      {
 42         "name": "int_param",
 43         "description": "",
 44         "integerValue": 1
 45      },
 46      {
 47         "name": "bool_param",
 48         "description": "",
 49         "booleanValue": "true"
 50      }
 51      ]
 52   },
 53   ### In this section, the parameters represent messages in the Nimbus format that can enter and exit the component.
 54   ### Nimbus messages viewed on Nimbus web are equivalent to ROS messages published between components.
 55   "streams": {
 56      "inputStreams": [
 57      {
 58         "name": "scan",                              ### Nimbus stream name
 59         "description": "",
 60         "streamMode": "STREAM_MODE_TOPIC",           ### Defines stream type (topic/service) inputs: "STREAM_MODE_TOPIC"/"STREAM_MODE_SERVICE"
 61         "ros_topic": {
 62            "topic": "/scan",                          ### The topic name used inside the ROS workspace
 63            "type": "Messages.sensor_msgs.LaserScan",  ### ROS message stream type
 64            "qosProfile": ""                           ### ROS2 parameter, documentation: https://docs.ros.org/en/humble/Concepts/About-Quality-of-Service-Settings.html
 65      }, {
 66         "name": "odom",
 67         "type": "Nimbus.Core.Messages.Ros1.Messages.nav_msgs.Odometry", ### "type" can be the Odometry stream or Pose stream.
 68         "ros_tf": {  ,                                                  ###  Transforms the input Odometry stream to the reference frame inside the component.
 69            "base_frame": "odom",
 70            "child_frame": "base_link",
 71            "rate": 10.0
 72         }
 73      },
 74      "latched": false,                                ### If set to true, saves the last published message
 75      "maxRate": 0                                     ### Defines the component's max publish rate from the agent to the backend
 76      }
 77      ],
 78      "outputStreams": [
 79      {
 80         "name": "map",
 81         "description": "",
 82         "streamMode": "STREAM_MODE_TOPIC",
 83         "ros_topic": {
 84            "topic": "/map",
 85            "type": "Messages.nav_msgs.OccupancyGrid",
 86            "qosProfile": ""
 87      }, {
 88         "name": "robot_pose",
 89         "type": "Messages.geometry_msgs.Pose",  ### "type" can be Odometry stream or Pose stream
 90         "ros_tf": {                             ### Transforms the tf output stream of the component to the reference frame
 91            "base_frame": "map",                  ### Of the robot pose.
 92            "child_frame": "base_link",
 93            "rate": 10.0
 94         }
 95      },
 96      "latched": false,
 97      "maxRate": 0,
 98      },
 99      ]
100   },
101   ### This section allows the component to view all devices using other components.
102   "ros": {
103      "base_frame": "base_link",  ### Platform's base frame
104      "rate": 10.0,               ### rate of TF meseeages publish if needed
105      "publishTfDevices":true,    ### Nimbus agent will create TF's from the device location in relation to base_frame and publish to the component
106      "rosMasterUri": "",         ### Equals to: export ROS_MASTER_URI=http://ip:11311 command
107      "rosIp": "",                ### Equals to: export ROS_IP=ip command
108      "ros2DomainId": 0           ### Equals to: export ROS_DOMAIN_ID=number command
109   }
110   ### The section is used for configuring the component to access a particular device.
111   ### the physical device is identified if maching all the keys provided
112   "requiredDevices": [
113         {
114         "name": "laser",                    ### Device name
115         "info": {
116            "type": "USB_PORT_TYPE_SERIAL",   ### Device type
117            "productId": "ea60",              ### Device product id
118            "vendorId": "10c4",               ### Device vendor id
119            "serial": "",
120            "vendorName": "",
121            "productName": "",
122         },
123         "mountAs": "/dev/ttyUSB0"           ### Used by Docker container
124         }
125      ]
126}

Note

Using the modified “environment” below, you can run a component as a native ROS process. Substitute this “environment” section in the above script when using a local component (ROS without docker) without the need to dockerize. This requires ROS to be installed on the robot’s computer.

 1{
 2   "environment":
 3   {
 4      "rosLocalInfo":
 5      {
 6         "PackageName": "hector_mapping",          ### The name of the package that containes the launch file we want to execute
 7         "launchFile": "mapping_default.launch",   ### The name of the launch file that we want to execute
 8         "rosVersion": "",                         ### The ros version that installed on the robot's computer
 9         "dependencies": [],
10         "workspaceSetup": "/opt/ros/melodic/setup.bash",  ### The full path of the setup.bash file which is located in the workspace that we want to "source"
11         "required": true
12      }
13   }
14}

~~~

Publish to Nimbus Hub

Note

Only Nimbus organizations can publish to Nimbus hub

  1. From the Side bar, click Components.

  2. Click the Add component button. The Add Component screen opens.

    Nimbus Hub
  3. In the respective text boxes, enter the component’s description and relevant tags. Optional: From the Category drop-down list, select a component category.

  4. From the drop-down list, select a license type. Note: If the Public toggle is set, a warning Please check the license is displayed.

  5. Click JSON upload button and select the component definition JSON file from the directory. The uploaded file’s name appears next to the Upload JSON button.

  6. Optional: To upload an image of the component, click Upload Image, select the file from the directory, and click Open.

    A thumbnail of the uploaded image appears in the Add Component pane, and an Image updated message is briefly displayed.

  7. Use the slider button to select Private or Public.

    Selecting Public will publish the component to Nimbus Hub.

  8. Click the License box and select a license type.

  9. Optional: In the Add tags text box, add meaningful tag names. Tip: Providing tags can be useful for finding and grouping related components during a search of your Docker image repository.

  10. Click Create button. The message Component has been created is briefly displayed at the bottom of the screen.

  11. To view the newly created component, select Components from the Side bar. The new component’s details appear at the top of the Your components list.