Skip to content

Configuration


Overview

JCS system configuration can be broadly split into two parts; network structure configuration then device and process configuration.


Network Configuration

A JCS network is configured via YAML configuration files.

structure.yaml defines the network layout, which processes run on which devices, and defines any signal routes.

Devices and processes are configured via individual configuration files, one for each device or process.


Configuration File Directory Structure

To make navigation and locating configuration files easier, device and process configuration files are stored under a directory structure that reflects the layout of the network.

For example:

*
├─ structure.yaml
├─ dev_host.yaml
├─ joint_controller_0/
│  ├─ dev_joint_controller_0.yaml
│  ├─ proc_process_0.yaml
│  ├─ dev_device_0/
│  │  └─ dev_device_0.yaml
│  └─ dev_device_1/
│     └─ dev_device_1.yaml
└─ joint_controller_1/
   ├─ dev_joint_controller_1.yaml
   └─ dev_device_2/
      ├─ dev_device_2.yaml
      └─ proc_process_1.yaml

In this example we can quickly see that there are two joint controllers. 'joint_controller_0' has a process instantiated on it and two devices 'device_0' and 'device_1' are physically connected to it.

'joint_controller_1' has 'device_2' physically connected to it and 'device_2' has a 'process_1' instantiated on it.

structure.yaml and dev_host.yaml configuration files reside in the root of the directory structure.


structure.yaml

structure.yaml defines the following:

  • The network structure and which devices are physically plugged in where.
  • Which processes run on which devices.
  • Signal mappings between devices, processes and dev_host.

Layout and usage

structure.yaml contains a collection of YAML entries that represent all devices and processes attached to the system. Each entry contains the name and device or process type, whether the device has a network (any other devices attached to it), whether the device has any processes and any signals that the device or process might ingest.

structure.yaml requires dev_host to be defined first, followed by any devices or processes:

Host entry

structure.yaml requires that the dev_host entry is the first device defined with the name HOST.

The dev_host entry requires there to be at least one device on the network and at least one input_signal defined.

Configure the dev_host entry with the following attributes:

  • name : Required dev_host name of HOST as seen in Host configuration.
  • type : Required device type of dev_host.
  • network : The network entry defines the port and any devices attached to dev_host
    • port : dev_host network port (currently set to 0) as configured in Host transport configuration.
    • devices : A list of JCS device names attached directly to the host computer. Typically JCS Joint Controllers.
      • name : Device name
  • input_signals: A list of input signals coming from the network devices into dev_host.
    • rate : The rate name that this list of signals will be collected at.
      • signals : The list of signal sources and names being collected at this rate.
        • source : Signal source name. This will be a device or process on the JCS network.
        • name : Actual signal name.
Example
- name: HOST
  type: dev_host
  network:
    - port: 0
      devices:
        - name: device_0
        - name: device_1
  input_signals:
    - rate: base
      signals:
        - source: device_1
          name  : signal_3
        - source: device_0
          name  : signal_0
        - source: device_1
          name  : signal_0

    - rate: 10Hz
      signals:
        - source: device_0
          name  : signal_6

The above example shows the following:

  • Signal order is not important.
  • dev_host has two devices attached to the high speed Ethercat network port.
  • dev_host has data moving about the system at two rates, the base rate and at 10Hz.
Device and process entries

All other devices and processes may be presented in any order. Whether the device or process requires any input signals is dependent on the device (see JCS Devices and JCS Processes). Whether a device supports processes is also dependent on the device.

The device or process name and type must be present. A device name must appear in a network entry of a parent device (or dev_host). A process name must appear in a processesentry of a parent device.

Configure the device or process entry with the following attributes:

  • name : Required device or process name as set in the device or process configuration file.
  • type : Required device or process type.
  • network : The network entry defines the port and any devices attached. (Devices only)
    • port : Device network port that the devices are physically connected to.
    • devices : A list of JCS device names attached to the port.
      • name : Device name.

IMPORTANT:

The order that the devices are listed must reflect the physical order in which the devices are plugged in. If a device is unplugged from the network, it must be removed from the network section.

  • input_signals : A list of input signals going into the device.

    • rate : The rate name that this list of signals will be collected at.
      • signals : The list of signal sources and names being collected at this rate.
        • source : Signal source name. This will be dev_host, or another device or process on the JCS network.
        • name : Actual signal name.
  • processes : A list of processes that will run on this device.

    • rate : The rate at which the following list of processes will be ticked.
      • names : A list of process names that run at the above rate.
        • name : Process name.
Example

Consider the following structure.yaml example:

- name: HOST
  type: dev_host
  network:
    - port: 0
      devices:
        - name: joint_0
  input_signals:
    - rate: base
      signals:
        - source: joint_0
          name  : an_1
        - source: motor_0
          name  : w_m
        - source: motor_speed_ctl
          name  : u

    - rate: 10Hz
      signals:
        - source: motor_0
          name  : t_ave

#####################################
- name: joint_0
  type: dev_joint_controller
  network:
    - port: 2
      devices:
        - name: motor_0
#####################################
- name: motor_0
  type: dev_motor_controller
  input_signals:
    - rate: base
      signals:
        - signal_name: i_q
          source     : motor_speed_ctl
          name       : u
  processes:
    - rate: base
      names:
        - name: motor_speed_ctl
#####################################
- name: motor_speed_ctl
  type: proc_pid
  input_signals:
    - rate: base
      signals:
        - signal_name: setpoint
          source     : HOST
          name       : vel
        - signal_name: measurement
          source     : motor_0
          name       : w_m

This example shows all the functionality of structure.yaml.

Example layout

When examining the network layout, we can look at each device, then read it's network entry. Note here that for each network entry, there must be a port defined, followed by a list of devices attached to the port. Also note that for each device entry, there must be a corresponding primary entry in structure.yaml. dev_host will fail to start if there are missing entries.

Working down from the top, it can be seen that:

  • dev_host has a network of devices. In this case it is just one device - joint_0. If we search the list of primary entries in structure.yaml we find that joint_0 is defined and configured.
  • joint_0 has a network of devices. In this example it is just one device, motor_0 physically attached to the joint controllers port 2. If we search the list of primary entries in structure.yaml we find that motor_0 is defined and configured.
Example processes

When examining what processes are running on the system, we can look at each device, then read it's processes entry. Working down from the top, it can be seen that:

  • dev_host has no processes. (dev_host is not capable of running JCS processes.)
  • joint_0 has no processes.
  • motor_0 has processes defined. In this example, it is just one process - motor_speed_ctl. The rate at which motor_speed_ctl is ticked is defined as base. If we search the list of primary entries in structure.yaml we find that motor_speed_ctl is defined and configured.
Example signals

When examining signal routing on the system, we can look at each device and process, then read it's input_signals entry. Working down from the top, it can be seen that:

  • dev_host is taking in three signals at base rate and one signal at 10Hz.
  • Device motor_0 takes in one signal from the process motor_speed_ctl at base rate.
  • Process motor_speed_ctl takes in one signal from dev_host. In this case it is a velocity set point. motor_speed_ctl also takes in a measurement signal from motor_0.

dev_host Configuration

dev_host.yaml stores the configuration for dev_host:

  • Host rates configuration.
  • Host network interface configuration.
  • Any host behaviour configuration.
  • Any signals that originate from dev_host.
  • Startup and shutdown lists.

Host configuration

The following entries are required:

  • name : Define the dev_host name as HOST. This parameter is fixed and required.

  • device_id : dev_host device ID. The device ID should be set to [0, 0, 0] and is required.

Example

name: HOST
device_id: [0, 0, 0]

Host rates configuration

Base rate

JCS is a real time synchronous system and requires a base frequency to be set. The base frequency defines the rate at which the real time thread will cause the JCS network to propagate forward by one timestep and exchange data with the network and all devices and processes.

Practical base frequencies are between 500Hz and 2kHz - 3kHz(depending on network complexity and configuration).

Sub rates

JCS supports running processes and exchanging signals at rates slower than the base rate.

Sub rates are useful for:

  • Receiving slow telemetry data
  • Running normal processes that do not need to execute at the base rate.
  • Running complex processes that may take longer than the base rate to actually execute.

Device rate

On certain devices JCS supports running processes and exchanging signals at rates much higher than the base rate.

Some examples of device rate uses might be:

  • A motor controller might run a high gain position controller at 15kHz for a quasi-direct drive actuator.
  • A motor controller might run a solver process to inject sine and cosine signals into the current controllers at a high rate to obtain inductance and resistance information about the motor.
Device rate requirements

Device rates have the following requirements and restrictions:

  • The name device cannot be changed.
  • Device rates are available only on selected devices. (Device rate support is indicated in device Software Reference under the JCS Interface heading).
  • A device rate signal may not cross the network from one device to another.
  • A device rate signal may be passed between processes at the device rate within the device.

Configuration

The tag base_config is used to configure JCS rates and supports the following attributes:

  • base_freq_hz : Defines the base tick rate of the JCS system.

  • sub_rates : The sub_rates entry is a list that define each sub rate, with the the following attributes:

    • name : The sub rate name, so that it may be referenced in the rate sections in structure.yaml.

      • Set name to device to use device rates anywhere on the system.
    • freq_hz : The sub rate frequency.

      • freq_hz must be a whole integer divisor of the base rate set by base_freq_hz.
      • freq_hz must be more than 10 times slower than base rate set by base_freq_hz.
      • If device is specified in name, then freq_hz is not required.

Example

base_config:
  base_freq_hz: 1000
  sub_rates:
    - name    : 10Hz
      freq_hz : 10
    - name    : device

Host transport configuration.

dev_host transport currently consists of a high speed Ethercat connection, via the Simple Open Ethercat Master (SOEM) project.

The tag transport_config is used to configure dev_host transport, with the following attributes:

  • port : Defines the port to be configured. Fixed to a value of 0.
  • type : Defines the transport type. Fixed to transport_ecat_soem.
  • ifname : Defines the Linux interface name that the Ethercat connection uses. Use ifconfig or equivalent to find this.

NOTE:

transport_config is a list of transport entries, however only 1 entry is currently supported.

Example

transport_config:
  - port: 0
    type: transport_ecat_soem
    ifname: enp3s0

Host behaviour configuration

dev_host operational behaviour may be configured via the behaviour tag.

The following attributes may be configured:

  • autostart_nodes : Autostart nodes propagates the start command to all devices upon a call to dev_host start(). Set to false if you wish to manage node startup manually, for example, in the list_start command list. autostart_nodes is enabled by default.

  • autostop_nodes : Autostop nodes propagates the stop command to all devices upon a call to dev_host stop(), except for any device in an error state. A device in an error state will remain in the error state until reset() is called. Set to false if you wish to manage node stop manually, for example, in the list_stop command list. autostop_nodes is enabled by default.

  • get_errors_at_shutdown : Causes dev_host to examine all devices for errors at shutdown, if no e-stop condition is present. If an e-stop condition is present all nodes will be examined for errors, regardless of this setting. get_errors_at_shutdown is enabled by default.

Example

behaviour:
  autostart_nodes: false
  autostop_nodes:  false
  get_errors_at_shutdown: false

Host signals configuration

dev_host signals are defined as the signals that come into the system from the user via the real time synchronous API, then propagate out to the network devices or processes. These signals are typically controller commands.

dev_host signals are configured via the signals tag. Configure each signal with the following attributes:

  • name : Required signal name.
  • 'type' : Required signal data type. JCS currently only supports float32 as an input signal type.
  • 'lim_h' : Optional high limit. The high limit has no effect on the operation of the system. The limits may be queried via the signals API as useful information for the user.
  • 'lim_l' : Optional low limit. The low limit has no effect on the operation of the system. The limits may be queried via the signals API as useful information for the user.

NOTE:

Currently a maximum of 128 input signals are supported.

Example

signals:
  - name: joint_0_th
    type: float32
    lim_h: 100.0
    lim_l: -100.0
  - name: joint_0_tau
    type: float32
  - name: joint_1_th
    type: float32
    lim_h: 200.0
    lim_l: -100.0
  - name: joint_1_tau
    type: float32

Host task lists

When starting or stopping devices it is useful to send parameters to groups of devices, so they might perform some action as the system starts or stops.

Useful examples of this might be:

  • Starting a motor controllers current controller before starting the system.
  • Aligning and zeroing an encoder on a motor controller before starting a system.
  • Pre-charging any capacitance on the main motive power DC-bus before starting a system.
  • Bleeding the DC-bus capacitors to a safe voltage level after shutting down a system.

Typically this might be done in code, for example, during a state transition and starting a system (and this is still possible). Performing these actions in code can become cumbersome, as recompiling will be required to alter the actions.

jcs_host supports a simple task system that allows lists of commands to be executed at ready, start, stop and shutdown.
The lists and commands are defined within dev_host.yaml and thus are simple to alter.

Please note: The structure of jcs_host commands is preliminary and subject to change.

Configuring a list

Configure a list with the following:

  • name : List name
  • device_groups : Group similar devices together in a group. Each list entry will be applied to each device in the group.

  • group_id : Assign a numerical ID to reference the group in the task entry.

  • devices : A list of devices within the group.

    • name : The name of the device to send a command to.
  • tasks : A list of command entries

Task: cmd

cmd writes a command or value out to a device:

  • type : cmd
  • group : Reference the groupd_id of devices to send this command to.
  • write : The actual command to write out
Task: delay

delay delays for a number of milliseconds. Note: The delay will be approximate as task lists are executed in the non-realtime thread.

  • type : delay
  • delay_ms : Number of milliseconds to delay for (approximate)
Task: while

while waits for a boolean condition to become true, before proceeding to the next task entry. The condition is polled every 5ms. If the condition is not met, while will timeout after 4 seconds.

  • type : while
  • group : Reference the group_id of devices to poll for a condition.
  • condition : The boolean condition which when returned will cause while to successfully exit. Valid conditions are: true, false.
  • read : The command to read from. while will internally call read_boolean and will fail if the command to read is not boolean type.

Example

A common use of task lists is to start a motor controller, zero the encoder, then start the current controller:

In the following example, the start list causes the following to happen:

  • MC_0 is started and given some time to calibrate and become ready.
  • MC_0 is commanded to start its alignment procedure.
  • The task list waits (with a while) until the alignment procedure is in the dwell phase, by polling the command align_in_dwell.
  • The task list then delays for 1 second before zeroing the encoder and exiting the alignment procedure.
  • The task list then repeats for MC_1 and MC_2 (as they appear in the device_groups)

  • The task list then starts the current controller on MC_0

  • This task list then repeats for MC_1 and MC_2
list_start:
  - name: mc_align
    device_groups:
      - group_id: 0
        devices:
          - name: MC_0
          - name: MC_1
          - name: MC_2
    tasks:
      # Start mc's so we can align
      # This also starts the mc's encoder and estimator
      - type  : cmd
        group : 0
        write : start
      # Wait for the mc to calibrate and become ready
      - type  : delay
        delay_ms: 200

      # Configure the controller for alignment mode
      - type:  cmd
        group: 0
        write: controller_mode
        enum:  test_align
      # Enable the controller
      - type:  cmd
        group: 0
        write: controller_start
      # Wait for d-axis to become energised
      - type  : while
        group : 0
        condition: true
        read  : align_in_dwell
      # Snooze into dwell for a bit      
      - type  : delay
        delay_ms: 1000
      # Zero the motor position
      - type  : cmd
        group : 0
        write : encoder_position_zero
      # Exit align mode
      - type  : cmd
        group : 0
        write : controller_stop
      - type  : delay
        delay_ms: 100

  - name: mc_start_i_ctl
    device_groups:
      - group_id: 0
        devices:
          - name: MC_0
          - name: MC_1
          - name: MC_2
    tasks:
      # Configure the controller for DQ current mode
      - type:  cmd
        group: 0
        write: controller_mode
        enum:  current_dq
      # Enable the controller
      - type:  cmd
        group: 0
        write: controller_start

Device Configuration

All JCS devices require a YAML configuration file to be defined as devices typically retain no configuration information through a power cycle and must be configured at each startup.

Device naming convention

All device YAML configuration files are prepended with 'dev_'.

For example: Device 'joint_0_ankle_motor_0' is defined in structure.yaml under the 'name' entry. The file name shall be 'dev_joint_0_ankle_motor_0.yaml'.

YAML configuration

Name

All JCS devices require a unique name. The device name is used to reference the device in structure.yaml

Configure the name with:

name: device_name_0

Device ID

All JCS devices require a device ID. The device ID is used to identify the device on the network. At startup dev_host queries the expected device and compares it's device ID with the configuration file device ID. dev_host will fail to start if the IDs do not match.

The device ID can be found:

  • Printed on a sticker attached to the device as a group of three numbers.
  • Via querying the device via dev_host when configured in a simple network. See dev_host tools section.

Configure the device ID as an array with three elements:

device_id: [4784162, 1413697558, 540356662]

Redefining names and units

Some signals support having the signals name and units renamed. This is typically only applicable to analog signals. If a signal is able to be renamed, it is noted in the JCS Network Configuration.

Rename a signal with:

# Redefine an_0 name and units
an_0_name:  temperature_0
an_0_units: degC

Once the signal has been renamed, it must be referenced in structure.yaml with the new name.

parameters

Any configuration parameters listed under the parameter heading will be sent to the device during the start_network phase of JCS startup. These parameters are used to configure the devices to the state required for operation.

Define any configuration parameters with:

# Config parameters to send to device
parameters:
  an_2_gain:            0.2658691406 # 330 * (3.3 / 4096)
  an_2_offset:          50.0
  an_2_limit_warning_h: 19.0
  an_2_limit_warning_l: 10.0
  an_2_limit_error_h:   100.0
  an_2_limit_error_l:   -10.0

All device configuration parameters are detailed under each device's software reference.


Process Configuration

All JCS processes require a YAML configuration file to be defined.

Process naming convention

All process YAML configuration files are prepended with 'proc_'.

For example: Process 'joint_0_ankle_motor_0_speed_ctrl' is defined in structure.yaml under the 'name' entry. The file name shall be 'proc_joint_0_ankle_motor_0_speed_ctrl.yaml'.

YAML configuration

Name

All JCS processes require a unique name. The process name is used to reference the process in structure.yaml

Configure the name with:

name: process_name_0

parameters

Any configuration parameters listed under the parameter heading will be sent to the process during the start_network phase of JCS startup. These parameters are used to configure the processes to the state required for operation.

Define any configuration parameters with:

# Configuration parameters to be sent to process
parameters:
  proc_pi_kp: 0.1
  proc_pi_ki: 1.0
  proc_pi_limit_out_h: 6.0
  proc_pi_limit_out_l: -6.0
  proc_pi_limit_integrator_h: 6.0
  proc_pi_limit_integrator_l: -6.0

All process configuration parameters are detailed under each process's Configuration Parameters section.