Recap
Let's recap what we've seen in this Basics section.
Workspace
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
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 (syskit_basics
becomes SyskitBasics
).
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 -rROBOT_NAME
argument to specify which configuration should be loaded.
It is possible to reuse models from another bundle by using Roby.app.register_app
either globally in config/init.rb
or per-robot in the Robot.init
block of the robot
configuration file. Example
Within bundles:
- separate SDF models are saved within
models/sdf/
- SDF scenes are saved within
scenes/#{scene_name}/#{scene_name}.world
- compositions are in
models/compositions/
- ruby tasks are in
models/compositions/
- orogen extension files are in
models/orogen/
- profiles are in
models/profiles/
- orogen configuration files are in
config/orogen/
. Configuration-specific files (e.g. inconfig/orogen/gazebo/
) take precedence. - within the Syskit model folders (
compositions/
andprofiles/
), 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 thegazebo
configuration). The generators enforce this when given the-rROBOT_NAME
option. - the folder structure in
models/
maps one-to-one to the folder structure intest/
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 cmp 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
_child
suffix. Ports are accessed with the port name and the_port
suffix. This is how connections are made:source_child.out_port.connect_to sink_child.in_port
-
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 components
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
using_task_library "name_of_orogen_project"
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
import_types_from "name_of_orogen_project"
The corresponding types are accessible under the Types
object, e.g.
Types.base.samples.RigidBodyState
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
Ruby Tasks
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 common_models
bundle's ConstantGenerator
.
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
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 use
call.
Moreover, profiles allow to specify arguments to compositions in the process
of definition.
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
dots !
-
arguments are set with
with_arguments
CompositionModel.with_arguments(arg_name: arg_value)
CompositionModel.use('child_name' => model)
replacesCompositionModel
'schild_name
child with the given model.model
can itself be refined byuse
andwith_arguments
.CompositionModel.use(model)
replaces anyCompositionModel
child whose model is compatible withmodel
bymodel
.-
a definition or device can itself be used as
model
orCompositionModel
in 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)
Configuration
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
Deployments, Actions
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.