config.json

Set the mode, file locations, features, server, real-time and task settings a Motorcortex application starts with.

config.json holds the start-up settings of a Motorcortex application: whether it runs on real hardware or in simulation, where its other files are, which features it adds, how clients connect and how fast each task runs. The application reads it once, at start-up, from the path in motorcortex.conf.

/etc/motorcortex/config/
└── config.json

A change to config.json takes effect at the next start of the application.

All options at a glance

These are the blocks of config.json, with their keys and defaults. Click a card to open its tab below.

A required key that is missing is reported in the log as Failed to find field. The application ignores keys it does not read, which is how the standard configuration keeps a second value at hand: "Mode_": "Production" sits next to "Mode": "Simulation" and does nothing until you swap the names.

The complete config.json of the standard robot application
{
  "Mode_": "Production",
  "Mode": "Simulation",
  "Drive": "cia402",
  "LogLevel": "Debug",
  "Path": {
    "Fieldbus": "io/master.xml",
    "Control": "control/control.xml",
    "UserParameters": "user/parameters.json",
    "Linking": [
      "linking/base.link.json",
      "linking/referencing.link.json"
    ],
    "Mechanism": "mech/mech-parameters.xml",
    "License": "/etc/motorcortex/license.lic",
    "Log": "/var/www/motorcortex/log",
    "Persistence": "control/persistence.bin"
  },
  "AGVControl": {
    "Enable": false,
    "MobilePlatformType": "differential",
    "Linking": "linking/agv-control.link.json"
  },
  "AxesControl": {
    "Enable": true,
    "NumberOfAxes": 6,
    "NumberOfActuators": 6
  },
  "ManipulatorControl": {
    "Enable": true,
    "Linking": "linking/manipulator-control.link.json"
  },
  "UserFrame": {
    "Enable": true,
    "Amount": 3
  },
  "MachineControl": {
    "Enable": false,
    "NumberOfJoints": 6,
    "Linking": "linking/machine-control.link.json"
  },
  "Joystick": {
    "Enable": false,
    "Amount": 1,
    "Linking": "linking/joystick.link.json",
    "Device_0": "/dev/input/js0",
    "Device_1": "/dev/input/js1",
    "Device_2": "/dev/input/js2"
  },
  "SpaceNav": {
    "Enable": false,
    "Linking": "linking/space-nav.link.json",
    "Device": "/dev/input/by-id/usb-3Dconnexion_3Dconnexion_Universal_Receiver-event-joystick"
  },
  "CollisionDetector": {
    "Enable": false,
    "Amount": 6,
    "Linking": "linking/collision-detector.link.json"
  },
  "SignalGenerator": {
    "Enable": false,
    "Amount": 3,
    "Linking": "linking/signal-generator.link.json"
  },
  "SetpointGenerator": {
    "Enable": false,
    "Amount": 3,
    "Linking": "linking/setpoint-generator.link.json"
  },
  "ForceDimension": {
    "Enable": false,
    "Name": "Lambda7",
    "Serial": 0,
    "Linking": "linking/force-dimension.link.json"
  },
  "SafetyChannelSelector": {
    "Enable": false,
    "NumberOfChannels": 6,
    "Linking": "linking/safety-selector.link.json"
  },
  "MotionPlayer": {
    "Enable": false,
    "Path": "motionfiles",
    "Linking": "linking/motion-player.link.json"
  },
  "Tool6DofAdmittance": {
    "Enable": false,
    "Amount": 1
  },
  "Bartending": {
    "Enable": false,
    "Amount": 1
  },
  "UdpComm": {
    "Amount": 1,
    "Enable": false,
    "Configurations": [
      {
        "Name": "Device101",
        "Enable": true,
        "ListenOnPort": 16385,
        "ReplyToSource": false,
        "SendCycleTime": 0.1,
        "SendToHost": "192.168.2.101",
        "SendToPort": 16385,
        "Packets": "udp/udp.packets.json",
        "Linking": "udp/udp.link.json"
      }
    ]
  },
  "WeavingMotion": {
    "Enable": false,
    "Amount": 1,
    "Linking": "linking/weaving-motion.link.json"
  },
  "XsensIMU": {
    "Enable": false,
    "Device": "/dev/ttyUSB0"
  },
  "Server": {
    "Default": {
      "URL": "wss://*:5568:5567",
      "Direction": "listen",
      "Login": "disable",
      "Certificate": "/etc/ssl/certs/motorcortex.pem"
    }
  },
  "Realtime": {
    "Isolate": [0, 1],
    "Allocate": 16
  },
  "Task": {
    "Control_task":   { "Sched": "Realtime", "Cpu": [0], "Prio": 80, "Dt": 1000 },
    "Fieldbus_task":  { "Sched": "Realtime", "Cpu": [1], "Prio": 80, "Dt": 1000 },
    "Simulator_task": { "Sched": "Realtime", "Dt": 1000 },
    "Logic_task":     { "Sched": "Realtime", "Dt": 10000 },
    "Logger_task":    { "Sched": "Normal", "Dt": 1000 },
    "IO_task":        { "Sched": "Realtime", "Dt": 1000 },
    "Comm_task":      { "Sched": "Normal", "Dt": 1000 }
  }
}

How paths are found

Every file location in config.json is either relative or absolute:

  • Relative ("io/master.xml"): starts in the folder of config.json, so on the controller in /etc/motorcortex/config/. The file travels with the package.
  • Absolute ("/etc/motorcortex/license.lic"): used as it is. The file stays where it is when you deploy another package.

This holds for the Path keys, the files a feature names, and the Accounts and Certificate of the server.

Keep the licence outside the package

/etc/motorcortex/config is a link to the folder of the active package, and each deploy creates a new folder. A licence stored inside the package, with a relative "License": "license.lic", therefore stays behind in the old folder when you deploy a new package. The standard configuration uses the absolute path instead, so every package deployed on this controller finds the same licence:

"Path": {
  "License": "/etc/motorcortex/license.lic"
}

See license.lic for what the licence does.

The options


Mode

Mode decides whether the application drives real hardware or simulates it.

Mode What runs
"Production" The application drives the real EtherCAT devices.
"Simulation" The application runs without hardware: the devices are simulated. Use it to try a configuration on a PC or a cloud machine.

The mode also decides which groups of the link files apply. To simulate only some devices while the rest run for real, see Simulating EtherCAT devices.

The application only runs in production when all three of these hold; otherwise it runs in simulation:

  • Mode is exactly "Production", with a capital P.
  • The command line in motorcortex.conf has no -s.
  • The licence is not a simulation-only licence, such as the one of a motorcortex.io cloud machine.

Drive

Drive (required) sets the drive protocol of the drive logic.

Value Protocol
"cia402" CiA402The standard device profile for servo drives on EtherCAT and CANopen. It defines the drive’s state machine and its operation modes, such as cyclic synchronous position (CSP). drives, the usual choice
"sercos" Sercos drives
"servo" Drives handled by the core’s servo drive logic

Case and spaces do not matter: "CiA 402" is read as cia402. With an unknown value the drive logic has no drives, and the log shows has unknown type.

LogLevel

LogLevel sets how much the application writes to its log. Each level shows its own messages and all more serious ones. Case does not matter.

Value Shows
"Debug" Everything, including debug messages
"Info" Information, warnings, errors and fatal errors. Default
"Warning" Warnings, errors and fatal errors
"Error" Errors and fatal errors
"Fatal" Fatal errors only
"Disabled" Nothing

An unknown value leaves the level at Info.

TimeScale

TimeScale (default 1.0) runs every task faster than real time, for example 10 for ten times as fast. The cycle times in the Task block stay the same for the calculations; only the wall-clock wait between cycles gets shorter. Use it in simulation only. A value below 1.0 is logged as an error and treated as 1.0.


Path

The Path block names the files the application always reads. A relative path starts in the folder of config.json.

Key Names Standard value
Fieldbus The EtherCAT bus configuration. Required. "io/master.xml"
Control The parameter values loaded at start-up. Parameters saved from Desk go to the same folder. Required. "control/control.xml"
Persistence The file that keeps persistent values across restarts. Created when it is missing. Required. "control/persistence.bin"
Mechanism The mechanism description. Read when ManipulatorControl is enabled. "mech/mech-parameters.xml"
UserParameters Your own parameters. Required. "user/parameters.json"
Linking The link files that always load, as one path or a list. Required. ["linking/base.link.json", "linking/referencing.link.json"]
License The licence. Required. "/etc/motorcortex/license.lic"
Log The folder the application writes its log to. Required. "/var/www/motorcortex/log"
ServicesConfig Service definition files, as one path or a list. Optional. not set
ExternalReset A command the application runs to reset external hardware. Used in production mode only. Optional. not set

The link files of a feature are not listed here: each feature names its own in its Linking key, see the Features tab.


Features

A feature block adds a part of the application to the parameter tree, such as the manipulator control or a joystick. The blocks belong to the application: the list below is that of the standard robot application, motorcortex-robot.

Most feature blocks share these keys:

Key What it does Default
Enable true adds the feature, false leaves it out. true for features with an Amount, false for the others
Amount How many copies to add. 3 adds three signal generators, SignalGenerator01 to SignalGenerator03. 1
Linking The link file of the feature, one path. It loads only when the feature is enabled. none

A valid licence sets how many copies of a feature you may add, and this also applies to NumberOfAxes, NumberOfJoints and NumberOfChannels. When you ask for more, the application adds as many as the licence allows and logs an error; a feature the licence does not name is not added. Without a valid licence every feature is added as configured, for the trial time.

The features of the standard robot application
Block Adds Its own keys
AxesControl The control loops of the axes. NumberOfAxes, NumberOfActuators (default: the number of axes)
ManipulatorControl Cartesian control of a robot arm. Reads Path Mechanism. none
UserFrame User frames for the manipulator. Amount
Tool6DofAdmittance Admittance control of the tool, with the manipulator. Amount
Bartending Bartending logic, with the manipulator. Amount
MachineControl Control of a machine with separate joints. NumberOfJoints
AGVControl Control of a mobile platform. MobilePlatformType, for example "differential"
SafetyChannelSelector Selection between safety channels. NumberOfChannels
MotionPlayer Replay of recorded trajectories. Path: the folder of the motion files
Homing Homing of the axes. none
CollisionDetector Collision detectors. Amount
SignalGenerator Signal generators. Amount
SetpointGenerator Setpoint generators. Amount
WeavingMotion Weaving motion. Amount
Joystick Joysticks. Amount, and Device_0, Device_1, … for the input device of each
SpaceNav A 3D mouse. Device
ForceDimension A haptic device. Only in builds with this device. Name, Serial
XsensIMU An Xsens inertial sensor. Only in builds with this device. Device
UdpComm UDP communication with other devices. Amount, and Configurations: a list with one entry per connection

UdpComm does not take a Linking of its own: each entry in Configurations names its own Packets and Linking file.

"UdpComm": {
  "Enable": true,
  "Configurations": [
    {
      "Name": "Device101",
      "Packets": "udp/udp.packets.json",
      "Linking": "udp/udp.link.json"
    }
  ]
}

Server

The Server block sets how clients such as Motorcortex Desk, a dashboard or your own program connect to the application. The application reads the server named Default:

"Server": {
  "Default": {
    "URL": "wss://*:5568:5567",
    "Direction": "listen",
    "Login": "disable",
    "Certificate": "/etc/ssl/certs/motorcortex.pem"
  }
}
Key What it does Default
URL Where the server listens, as transport://address:request_port:subscribe_port. wss://*:5568:5567 is a secure WebSocket on every network address, with requests on port 5568 and subscriptions on 5567. Required. none
Direction "listen" waits for clients. "connect" (or "dial") makes the application connect out to the address instead. "listen"
Certificate The TLS certificate for a secure (wss) connection. none
Login "disable" lets clients in without logging in. Any other value, or leaving the key out, turns login on. login on
Accounts The accounts.conf with the user accounts, used when login is on. Without it the built-in accounts apply. none
MaxUsers How many logged-in users can have control at the same time. A user beyond that gets read-only access. 1024
Threads How many worker threads handle requests. one per available CPU
Advanced server options

These tune the communication layer. Leave them out unless you are told to set them.

Key What it does Default
SaveChunkSize How many parameters a save handles per real-time cycle. 0: the built-in value
TransportThreads The size of the transport’s thread pool. 0: the built-in value
Publisher Scheduling of the publisher’s threads, as a block with Threads, Sched, Prio and Cpu, like a task. normal scheduling
PubSendBuf The publish queue depth per connection. 0: the built-in value
PubRouting "strict" changes how published data is routed; any other value broadcasts. broadcast
PubSendMode No longer used: the application logs a warning and ignores it.

Realtime

The Realtime block prepares the controller for real-timeReal-time means every cycle of a task finishes within its cycle time, every time. A control loop that is sometimes late makes the machine jerk or stop with an error. tasks when the application starts:

"Realtime": {
  "Isolate": [0, 1],
  "Allocate": 16
}
Key What it does Default
Enable false skips all real-time preparation. true
Isolate The CPUs to keep free for the real-time tasks. Other processes and interrupts are moved off them. none
Allocate Memory in MB to reserve and lock when the application starts, so a task never waits for memory. 0: none reserved

With real-time on, the application also sets every CPU to its performance frequency setting. Without a Realtime block, the application does no real-time preparation at all.

Isolating a CPU only helps when a task runs on it: give the tasks that must be on time the same CPUs in their Cpu key, see the Task tab.


Task

The Task block sets how often and with which priority each task of the application runs. A task runs a fixed set of modules every cycle.

"Task": {
  "Control_task":  { "Sched": "Realtime", "Cpu": [0], "Prio": 80, "Dt": 1000 },
  "Fieldbus_task": { "Sched": "Realtime", "Cpu": [1], "Prio": 80, "Dt": 1000 },
  "Logic_task":    { "Sched": "Realtime", "Dt": 10000 }
}
Key What it does Default
Dt The cycle time in microseconds. 1000 is 1 ms, so 1000 cycles per second. Required. none
Sched How Linux schedules the task: "Normal", or "Realtime" for real-time scheduling ("Realtime_fifo" is the same, "Realtime_rr" shares the CPU in turns between tasks of equal priority). Case does not matter. "Normal"
Prio The real-time priority, from 1 to 99; higher wins. Ignored with "Normal". 0: the lowest real-time priority
Cpu The CPUs the task may run on, as a list. not pinned
The tasks of the standard robot application
Task Runs Standard Dt
Fieldbus_task The EtherCAT bus and the axis control loops 1000 on CPU 1
Control_task Manipulator, machine and AGV control, the collision detectors, signal and setpoint generators, the watchdog 1000 on CPU 0
IO_task Joysticks, the 3D mouse and other input devices 1000
Simulator_task The simulator, UDP communication, the motion player and homing 1000
Logic_task The state machine, the drive logic, command interpreters, persistence, user parameters and services 10000
Comm_task The logger and the publisher that sends data to clients 1000

The standard file also has a Logger_task block; the robot application does not read it.

A shorter Dt gives faster control but costs more CPU time. To see whether a task keeps up, watch root/Control_task/utilization_max (or the same parameter under another task) in Motorcortex Desk: it is the highest share of the cycle time the task has used, in percent.


Simulator

The optional Simulator block chooses the simulator that stands in for the drives in simulation mode. Without it the application uses the basic simulator.

"Simulator": {
  "Type": "Basic"
}
Key What it does Default
Enable false turns off the simulator’s link file. true
Type Which simulator to use. Case does not matter. "Basic"
Model A model file for simulators that need one. none
Linking A link file for the simulator. Required when the block is there and enabled. none
Viewer true opens a viewer, for simulators that have one. false
Substeps Physics steps per task cycle, for simulators that subdivide a cycle. 1

Which types exist beyond Basic depends on how the application was built. An unknown type falls back to Basic.