config.json
13 minute read
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 ofconfig.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:
Modeis exactly"Production", with a capital P.- The command line in
motorcortex.confhas no-s. - The licence is not a simulation-only licence, such as the one of a motorcortex.io cloud machine.
Warning
In production mode the application drives real motors when it starts. Before you set "Mode": "Production" and restart, make sure the machine is safe to move and the emergency stop works.
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.