Let's recap what we've seen in this Basics section.
Autoproj is Rock's tool to manage (install and update) packages. "Packages" are the unit of integration of the Rock software. The role of a workspace build configuration is to ensure repeatability in the installation of a system's software
- the initial bootstrap installs a predefined set of packages as defined by a given build configuration
- packages are also added during development, when the functionality is required
You will ultimately create your own build configuration and package sets to share the state of your workspace with your coworkers.
Bundles are the package within which we create Syskit models and code. It is the place of integration.
From Syskit's point of view, a bundle has a toplevel namespace under which the rest of the app is defined. It is by default the CamelCased version of the bundle's folder name (
A given bundle may contain multiple Syskit app configurations. The entry point
for each configuration is a file in
config/orogen/. One usually creates one
bundle per class of system, and creates at least one configuration for
simulation and one for the live system. Syskit tools take a
argument to specify which configuration should be loaded.
It is possible to reuse models from another bundle by using
either globally in
config/init.rb or per-robot in the
Robot.init block of the robot
configuration file. Example
- separate SDF models are saved within
- SDF scenes are saved within
- compositions are in
- ruby tasks are in
- orogen extension files are in
- profiles are in
- orogen configuration files are in
config/orogen/. Configuration-specific files (e.g. in
config/orogen/gazebo/) take precedence.
- within the Syskit model folders (
profiles/), the convention is to have subfolders for models that are specific to a given robot configuration (e.g.
profiles/gazebo/for models that are specific to the
gazeboconfiguration). The generators enforce this when given the
- the folder structure in
models/maps one-to-one to the folder structure in
Components and Compositions
Components are the basic construction block in a Syskit system. Compositions are used to turn single components into more complex functional units, by binding the components together.
a composition template is created using
syskit gen NameOfComposition
an element within a composition is declared with
add, a component model (which can be another composition) and a name:
class MyComposition < Syskit::Composition add AnotherComponentModel, as: 'generator' end
within the composition model, a composition child is accessed using the child's name and the
_childsuffix. Ports are accessed with the port name and the
_portsuffix. This is how connections are made:
a composition can have ports, which are exports of its children ports. This works for both input and output ports. The exported port name is the same as the child's port name, but this can be overriden
export source_child.out_port export another_source_child.out_port, as: 'another'
oroGen is Rock's way to package C++ functionality into ready-to-use components with a standardized interface. These components are imported in Syskit's with
The other role of oroGen is to define types whose instances can be transferred between components. If one only wants to use a type defined by an oroGen project, but without using the associated components, one does
The corresponding types are accessible under the
Types object, e.g.
On import, Syskit builds a component model that represents the oroGen
component. This model is accessible as
OroGen.project_name.TaskName. It can
also be extended to reflect needs in the Syskit app, for instance
configuration, using extension files.
oroGen components provide a configuration interface as a set of properties.
These properties are filled using YAML configuration files stored in
config/orogen/, and may also be written in the
configure method of the
component's class, in the extension file.
A configuration file for a component class is generated with
syskit gen orogenconf name_of_orogen_project::NameOfModelClass
In a system, one often needs to do some small tasks that are either too small to warrant a full-fledged C++ component, or are so tied with the system integration that having a C++/Ruby boundary makes understanding hard. For these, Syskit allows to implement tasks in Ruby that are integrated within the Syskit execution but provide input and output ports to integrate with the rest of the components.
Because of the single-threaded nature of Syskit's execution engine, one must not use ruby tasks to perform a lot of work. This would freeze Syskit. Stick to simple tasks, and implement oroGen components for more complex ones.
A canonical example for such a task is the
Whenever runtime code is present in tasks, as it often is in ruby tasks, write tests.
A new Ruby task and associated test scaffold is generated with
syskit gen ruby_task class_name
Profiles are the models that contain functional networks. It is common to have
compositions made of abstract models, that is components that are not really
components - such as device models. These abstract components
can be replaced by actual components within the profiles with the
Moreover, profiles allow to specify arguments to compositions in the process
The model name given to
define in a profile is made out of a demeter
chain. In Ruby, one can
easily break the chain with a newline after each method call. Don't forget the
arguments are set with
CompositionModel.use('child_name' => model)replaces
child_namechild with the given model.
modelcan itself be refined by
CompositionModelchild whose model is compatible with
a definition or device can itself be used as
CompositionModelin all these calls, possibly from another profile:
define 'first', CompositionModel.use(first_test_dev) define 'second', first_dev.use(AnotherProfile.second_test_dev) define 'third', AnotherProfile.first_dev.use(second_test_dev)
Apart from the orogen configuration files, components can have arguments. The choice between a configuration file or a component argument is a matter of system design, but there are some guidelines.
Use task arguments when
- consistency between different components is necessary, as for instance the robot model
- a value is to be provided at runtime, as for instance a target pose
Use configuration files when
- the values are static (set once and seldom changed)
Arguments can be forwarded from a composition to its children using the following pattern:
class C < Syskit::Composition argument :robot add(ChildModel, as: 'generator'). with_arguments(robot: from(:parent_task).robot) end
Before they are used, components need to be deployed, that is associated with a
process and a name. This is done in the
requires block of the robot
configuration file with
Syskit.conf.use_deployment ComponentModel => 'component_name'
Actions are the basic block of interaction between a Syskit app and the outside
world. Moreover, the Main action interface, defined by the
actions block in
the robot configuration file is the interface that is being exposed through the
standard channels (IDE, shell).
Definitions from a profile are exported on the Main interface.
Next: We've only had a glimpse on the Syskit runtime workflow. Let's dig deeper