xcore_api Introduction
xcore_api is the C++ interface set used for Controller Plugin development. Plugins use these interfaces to access internal controller capabilities. Typical uses include plugin lifecycle management, custom RL command registration, motion command dispatch, robot state queries, IO and register read/write, EtherCAT/fieldbus communication, client-plugin-to-Controller-Plugin communication, and log reporting.
The current header version is 0.0.3. The corresponding controller version is defined in the interface package README.md. Ensure the xcore_api version used by the plugin matches the target controller version.
Usage Overview
Controller Plugins typically use xcore_api as follows:
- Include required headers in the plugin project, for example launch/launch_api.hpp and rl_cmd/morden_rl_cmd_api.hpp.
- Implement an entry module that inherits xcore_api::launch::LaunchAPI.
- In Init(), perform initialization such as loading configuration, initializing logs, and registering Hooks.
- In Start(), register commands, services, log codes, or start required background tasks.
- In Stop(), release resources, stop threads, or close bus connections.
- Use LAUNCH_MODULE or LAUNCH_MODULE_PRIORITY to auto-register the entry module with the controller.
Entry module example:
#include "launch/launch_api.hpp"
class ExamplePlugin : public xcore_api::launch::LaunchAPI {
public:
void Init() override {
// Plugin initialization, e.g. load config and initialize logs
}
void Start() override {
// Runs after all plugin Init calls complete, e.g. register commands, services, Hooks
}
void Stop() override {
// Release resources when the controller stops the plugin
}
};
LAUNCH_MODULE(ExamplePlugin)
Module Overview
| Module Directory | Main Headers | Purpose |
|---|---|---|
| launch | launch_api.hpp | Plugin entry and lifecycle management. |
| rl_cmd | morden_rl_cmd_api.hpp | Register custom RL commands, parse parameters, return execution results. |
| motion_cmd | motion_cmd_api.hpp | Generate and dispatch motion commands; supports linear, joint, arc, spiral, and other motion types. |
| sdk | sdk_cmd_api.hpp | SDK custom command interface; supports motion and non-motion commands entering the SDK command queue. |
| hooks | hooks_api.hpp, hooks_args_api.hpp | Register controller event callbacks, e.g. point changes, program jumps, start, pause, emergency stop. |
| states | states_api.hpp | Query and set controller state, e.g. auto/manual, power on/off, task space, simulation mode. |
| rl_task | rl_task_api.hpp | Query and control RL tasks, e.g. start, pause, stop, jump to line, get execution pointer. |
| io | analog_api.hpp | Read/write AI/AO/DI/DO/GI/GO signals and internal registers. |
| registers | function_code_api.hpp | Extend register function codes; supports custom register read/write logic. |
| ethercat | ecat_base_api.hpp | Operate EtherCAT slave PDO/SDO. |
| fieldbus | fieldbus_api.hpp | Create and operate fieldbus devices such as Modbus, Profinet, EIP, CC-Link. |
| endtool | endtool_api.hpp | Control end tools such as electric grippers via end-protocol passthrough; currently mainly wraps Modbus RTU. |
| service | service_api.hpp | Register Controller Plugin services for JSON communication between client plugins and Controller Plugins. |
| log | log_api.hpp | Initialize plugin-specific logs and provide plugin log macros. |
| user_log | user_log_api.hpp | Register and report multilingual user logs and runtime logs. |
| const_data | pose_api.hpp, ecat_api.hpp | Common data structures for pose, points, speed, tools, work objects, triggers, PDO/SDO, etc. |
| utils | filesystem_api.hpp, thread_pool_api.hpp, singleton_api.hpp | General utilities for JSON/file I/O, thread pool, singleton template, etc. |
launch: Plugin Entry Module
The launch module registers plugin entry objects with the controller. Entry classes must inherit LaunchAPI and implement Init(), Start(), and Stop().
Execution order:
- The controller loads the plugin dynamic library and constructs the plugin entry object.
- All plugin entry modules run Init() in priority order.
- After all Init() calls complete, Start() runs in priority order.
- When the controller stops or unloads the plugin, Stop() runs.
- Plugin objects are destroyed.
Common interfaces and macros:
| Interface / Macro | Description |
|---|---|
| LaunchAPI::Init() | Initialization phase; suitable for loading config, initializing logs, preparing data structures. |
| LaunchAPI::Start() | Start phase; suitable for registering commands, services, log codes, etc. |
| LaunchAPI::Stop() | Stop phase; suitable for releasing resources, stopping threads, closing device connections. |
| LaunchAPI::Register(priority, ptr) | Register an entry module; higher priority runs first. |
| LAUNCH_MODULE(ClassName) | Register an entry module with default priority 0. |
| LAUNCH_MODULE_PRIORITY(ClassName, priority) | Register an entry module with the specified priority. |
rl_cmd: Custom RL Commands
The rl_cmd module registers C++ implementations as custom commands callable from RL programs. Plugins can declare command names, parameter types, default parameters, look-ahead behavior, task limits, and step-back behavior, then read parameters in the execution function, call controller capabilities, or set return values.
Core concepts:
| Type / Interface | Description |
|---|---|
| ValueTypeAPI | Command parameter types, e.g. VALUE_INT, VALUE_DOUBLE, VALUE_STRING, VALUE_POSE, VALUE_TOOL, VALUE_WOBJ. |
| ArgTypeAPI | Describes a single parameter type; can set whether omission is allowed and default values. |
| RLCmdConfigAPI | Command configuration including function name, look-ahead type, task limits, step-back behavior. |
| ModernRLCmdAPI | Custom command builder for setting parameters and execution functions. |
| RLCallFrameAPI | Gets current command runtime context such as task name, file name, and line number; can also set return values. |
| SymbolVarBaseAPI | Command parameter access object; reads basic types, points, speed, tools, work objects, etc. |
| RegPluginCmdsAPI() | Registers commands with the controller. |
Common execution results:
| Return Value | Meaning |
|---|---|
| CMD_PROCESS_SUCCESS | Command succeeded; RL continues running. |
| CMD_PROCESS_ERROR | Command failed; current task is paused. |
| CMD_PROCESS_FATAL | Fatal error; RL stops. |
| CMD_PROCESS_IGNORE | Asynchronous command; task enters async wait. |
| CMD_PROCESS_EXTRA | Additional command execution; commonly used for motion commands. |
| CMD_PROCESS_RESCHEDULE | Request reschedule. |
Simplified example:
#include "rl_cmd/morden_rl_cmd_api.hpp"
void RegisterExampleCmd() {
xcore_api::rl_cmd::RLCmdConfigAPI cfg;
cfg.SetFuncName("ExampleCmd");
cfg.SetLookAhead(xcore_api::rl_cmd::WAIT_MOVE_PAUSE);
BEGIN_COMMAND_API(cfg)
PARAMS_API(xcore_api::rl_cmd::ArgTypeAPI(xcore_api::rl_cmd::ValueTypeAPI::VALUE_INT))
xcore_api::rl_cmd::RLCmdActionAPI action =
[](std::shared_ptr<xcore_api::rl_cmd::RLCallFrameAPI> frame,
std::vector<std::shared_ptr<xcore_api::rl_cmd::SymbolVarBaseAPI>> args) {
return [frame, args]() {
int value = args[0]->GetIntVal();
// Execute plugin logic here
return xcore_api::rl_cmd::CMD_PROCESS_SUCCESS;
};
};
EXECUTE_API(action)
REGISTER_COMMAND_API
}
Usage recommendations:
- Register commands in the entry module Start() phase when possible.
- Parameter types should match RL calling conventions; confirm parameter types before reading.
- Motion-related commands should set look-ahead behavior correctly to avoid breaking controller scheduling.
- When a return value is needed, set it through RLCallFrameAPI::SetReturnValue().
motion_cmd: Motion Commands
The motion_cmd module constructs and sends motion trajectories. It is typically used with custom RL commands: after the RL command parses parameters, point, speed, tool, work object, zone, and related data are packaged into MotionCmdArgsAPI and sent to the controller motion queue through MotionCmdAPI.
Supported motion types:
| Type | Description |
|---|---|
| MOVE_ABSJ | Absolute joint motion. |
| MOVE_J | Joint motion. |
| MOVE_L | Linear motion. |
| MOVE_C | Circular arc motion. |
| MOVE_CF | Full-circle motion; requires additional full-circle parameters. |
| MOVE_T | Weave motion; requires weave parameters. |
| MOVE_SP | Spiral motion; requires spiral parameters. |
Common configuration:
| Interface | Description |
|---|---|
| SetTargetPoint() | Set target point. |
| SetAuxPoint() | Set auxiliary point; used for multi-point motions such as arcs. |
| SetMoveType() | Set motion type. |
| SetTool() / SetWobj() | Set tool and work object. |
| SetSpeed() / SetZone() | Set speed and zone. |
| SetTriggers() | Set trajectory triggers. |
| SetCallback() | Set motion start, pause, finish, and error callbacks. |
| SetFinishInAdvance() | Terminate trajectory early; can be combined with Trigger/IO for search-style commands. |
| SendCmd() | Send a single motion command. |
| SendSegmentCmds() | Send multi-segment discontinuous continuous motion. |
| SendStepBackCmd() | Generate step-back command. |
Notes:
- Pose, speed, distance, and related data use SI units; position is in meters and angles are usually in radians.
- MOVE_CF, MOVE_T, and MOVE_SP require corresponding extended parameters.
- Custom motion commands should consider look-ahead, zone, and callback timing.
- For multi-segment trajectories, choose SendCmd() or SendSegmentCmds() based on application needs.
sdk: SDK Custom Commands
The sdk module adds plugin-defined SDK commands to the controller SDK command queue. It supports both motion and non-motion commands.
Core interfaces:
| Interface | Description |
|---|---|
| SDKCmdAPI | Base class for non-motion SDK commands. |
| BeforeProcess() | Optional pre-execution callback. |
| DerivedProcess() | Core execution logic; returns SUCCESS, PENDING, or ERROR. |
| AfterProcess() | Optional post-execution callback. |
| MordenSDKCmdAPI::SendSDKMotionCmd() | Send SDK motion command. |
| MordenSDKCmdAPI::SendSDKCmd() | Send ordinary SDK command. |
| MordenSDKCmdAPI::SetFinalSDKCmd() | Set command that breaks look-ahead. |
hooks: Controller Event Callbacks
The hooks module listens to internal controller events. After a plugin registers a Hook, the controller invokes the plugin callback when the corresponding event occurs.
Supported events:
| Event | Description |
|---|---|
| POINT_CHANGE | Point added, deleted, or modified. |
| PP_TO_MAIN | Program pointer jumps to main program. |
| PP_TO_LINE | Program pointer jumps to specified line. |
| B_START_RUN | Start run. |
| B_PAUSE_RUN | Pause run. |
| E_STOP_RUN | Emergency stop. |
Run modes:
| Run Mode | Description |
|---|---|
| SYNC_RUN | Synchronous execution; blocks the corresponding controller event. |
| ASYNC_RUN_IN_THREAD_POOL | Asynchronous execution in thread pool. |
| ASYNC_RUN_IN_RT_THREAD | Execution in real-time thread. |
Registration flow:
- Create HookDataAPI.
- Call SetEvent() to set the event.
- Call SetHook() to set the callback function.
- Call SetRunType() to set synchronous or asynchronous run mode.
- Call SetPriority() to set priority.
- Call RegisterHooksAPI() to register.
Note: Hook registration does not accept dynamic registration after plugin Start(). Do not perform time-consuming operations in synchronous Hooks to avoid blocking controller event flow.
states: Robot and Controller State
The states module queries or sets controller runtime state.
Common capabilities:
| Interface | Description |
|---|---|
| IsAutoMode() / SetAutoMode() | Query or set auto/manual mode. |
| IsPowerOn() / SetPowerOn() | Query or set power on/off state. |
| IsTaskSpaceReady() / SetTaskSpace() | Query or occupy task space. |
| IsRobotBusy() / SetRobotBusy() | Query or set robot busy state. |
| GetRunningState() | Get current run phase such as start, pause, single step, collision, emergency stop. |
| IsSimuMode() | Query whether current mode is simulation. |
Usage recommendations:
- Confirm current mode and task state before modifying controller state.
- Occupancy states such as SetRobotBusy() and SetTaskSpace() must be released in pairs; otherwise other modules may be unable to use the robot.
- When combined with motion or task control, first check whether execution is allowed.
rl_task: RL Task Control
The rl_task module controls and queries RL program tasks.
Common interfaces:
| Interface | Description |
|---|---|
| PPToMain() | Reset program pointer to main program. |
| IsProgramResetDone() | Check whether program reset is complete. |
| PPToLine() | Jump to specified task, file, and line. |
| PPToFunc() | Jump to specified function; mainly for debugging. |
| ModifyProgramLoop() | Modify program loop mode. |
| AlarmRLTask() | Wake specified task. |
| StartRun() / PauseRun() / StopRun() | Start, pause, or stop program. |
| PauseRunAndWaitIdle() | Pause program and wait for robot to stop. |
| GetPointedLine() / SetPointedLine() | Get or set program pointer. |
| GetExecLine() / SetExecLine() | Get or set motion pointer. |
| IsTaskExists() / IsTaskRunning() | Query whether task exists or is running. |
Note: After a failed jump, interpreter state may be uncontrollable; reload the task when necessary.
io: Signals and Registers
The io module currently mainly provides AI/AO/DI/DO/GI/GO signal and internal register access through the Analog singleton.
Signal interfaces:
| Signal Type | Read Interface | Write Interface |
|---|---|---|
| AI | GetAIValue() | Not supported |
| AO | GetAOValue() | SetAOValue() |
| DI | GetDIValue() | Not supported |
| DO | GetDOValue() | SetDOValue() |
| GI | GetGIValue() | Not supported |
| GO | GetGOValue() | SetGOValue() |
Register interfaces:
| Data Type | Read Interface | Write Interface |
|---|---|---|
| int16 | ReadInt16Register() | WriteInt16Register() |
| bool | ReadBoolRegister() | WriteBoolRegister() |
| float | ReadFloatRegister() | WriteFloatRegister() |
| bit | ReadBitRegister() | WriteBitRegister() |
| int32 | ReadInt32Register() | WriteInt32Register() |
| byte | ReadByteRegister() | WriteByteRegister() |
Helper interfaces:
| Interface | Description |
|---|---|
| IsAiExist() / IsAoExist() | Check whether analog signal exists. |
| IsDiExist() / IsDoExist() | Check whether digital signal exists. |
| IsGiExist() / IsGoExist() | Check whether group signal exists. |
| RegisterType() | Query register type. |
| RegisterWriteable() | Query whether register is writable. |
| CheckRegisterCanUsedAsIO() | Check whether register can substitute specified IO type. |
registers: Register Function Codes
The registers module extends register function codes. Plugins can declare a function code class, define supported register types, length, read/write attributes, and implement execution logic.
Core types:
| Type / Interface | Description |
|---|---|
| RegTypeAPI | Register data types: BIT, BOOL, BYTE, INT16, INT32, FLOAT. |
| FuncCodeCfgAPI | Function code configuration including name, supported types, length, writability. |
| FuncCodeAPI | Function code base class; must implement ExecFuncCode() and Clone(). |
| ReadIntRegValue() / ReadFloatRegValue() | Read register values associated with function code. |
| WriteIntRegValue() / WriteFloatRegValue() | Write register values associated with function code. |
| RegFuncCodeAPI() | Register function code with controller. |
Use DECLARE_FUNCTION_CODE_API and FUNCTION_CODE_EXECUTE_API macros to simplify declaration and implementation.
ethercat: EtherCAT Slave Access
The ethercat module operates EtherCAT slave PDO and SDO.
Data structures are defined in const_data/ecat_api.hpp:
| Data Structure | Description |
|---|---|
| PdoAPI | PDO data descriptor including baseIndex, byteOffs, byteSize, name. |
| SdoAPI | SDO data descriptor including index, subIndex, dateLen, timeOut, callback function, etc. |
Core interfaces:
| Interface | Description |
|---|---|
| EcatBaseAPI(slave_id) | Create EtherCAT operation object for specified slave ID. |
| GetPdoValue() / SetPdoValue() | Read or write PDO value. |
| GetSdoValue() / SetSdoValue() | Read or write SDO value. |
| RegisterPdo() / RegisterSdo() | Register PDO/SDO to corresponding offset or index. |
Note: When reading or writing PDO/SDO, the data pointer buffer size must match the object length.
fieldbus: Fieldbus
The fieldbus module wraps creation, configuration, open/close, register read/write, and DI/DO access for fieldbus devices.
Supported device types:
| Type | Description |
|---|---|
| MODBUS_TCP_MASTER / MODBUS_TCP_SLAVER | Modbus TCP master/slave. |
| MODBUS_RTU_MASTER / MODBUS_RTU_SLAVER | Modbus RTU master/slave. |
| PROFINET_SLAVER | Profinet slave. |
| EIP_SLAVER | EtherNet/IP slave. |
| CCLINK_IE_SLAVER / CCLINK_ECAT_SLAVER | CC-Link related slaves. |
Configuration classes:
| Configuration Class | Description |
|---|---|
| FieldbusCfgAPI | Basic bus configuration including device type, device name, endianness. |
| ModbusCfgAPI | Modbus configuration including IP, port, serial port, slave ID, register start address and count. |
| ProfinetCfgAPI | Profinet configuration including station name, network card, update cycle, slot module ID. |
| EipCfgAPI | EIP configuration including read/write register count and network card. |
| CCLinkCfgAPI | CC-Link configuration including protocol type, network card, occupied station count, baud rate, protocol version. |
FieldbusAPI provides unified access interfaces:
| Interface | Description |
|---|---|
| Open() / Close() | Open or close bus device. |
| ReadRegisters() / WriteRegisters() | Read or write registers. |
| GetDINum() / GetDONum() | Get DI/DO count. |
| GetDI() / SetDO() | Read DI or set DO. |
endtool: End Tools
The endtool module controls devices such as electric grippers through end-protocol passthrough. ModbusRTUEndtoolAPI currently wraps common Modbus RTU function codes:
| Interface | Modbus Function Code | Description |
|---|---|---|
| RWData() | Passthrough | Send and receive raw data directly. |
| ReadCoil_01() | 01 | Read coils. |
| ReadDiscreteInput_02() | 02 | Read discrete inputs. |
| ReadRegister_03() | 03 | Read holding registers. |
| ReadRegister_04() | 04 | Read input registers. |
| WriteCoil_05() | 05 | Write single coil. |
| WriteRegister_06() | 06 | Write single register. |
| WriteCoil_0F() | 15 | Write multiple coils. |
| WriteRegister_10() | 16 | Write multiple registers. |
This module is suitable for wrapping private protocols of end devices such as electric grippers, tool changers, and sensors.
service: Client and Controller Plugin Communication
The service module registers custom service protocols in Controller Plugins. After a client plugin sends a JSON request with plugin_name and key, the controller invokes the registered callback and returns the JSON data produced by the callback.
Interface:
int RegServiceAPI(
const std::string& plugin_name,
const std::string& key,
const std::function<Json::Value(const Json::Value&)>& func
);
Usage scenarios:
- Client plugin reads Controller Plugin state.
- Client plugin sends configuration to Controller Plugin.
- Controller Plugin returns device state, diagnostics, or business data to the client.
- Lightweight inter-plugin communication using custom JSON protocols.
log and user_log: Logging
The log module initializes plugin-specific logs and provides log macros:
| Macro | Description |
|---|---|
| LOG_DEBUG | Debug log. |
| LOG_INFO | Information log. |
| LOG_WARNING | Warning log. |
| LOG_ERROR | Error log. |
| LOG_FATAL | Fatal error log. |
Initialization interface:
xcore_api::log::InitLogAPI("log_dir", 10, 5);
Parameters are log directory, single log file size limit in MB, and log file count. Total log storage must not exceed interface limits.
The user_log module registers and reports user logs to the controller:
| Interface | Description |
|---|---|
| ConfigReportLogAPI() | Configure plugin multilingual logs. |
| ConfigEnglishReportLogAPI() | Configure English fallback logs. |
| RegisterReportLogAPI() | Register log configuration with controller and activate it. |
| ReportUserLogAPI() | Report multilingual user logs. |
| ReportRunLogAPI() | Report user runtime logs. |
Load log configuration in Init() and register log codes in Start().
const_data: Common Data Structures
const_data/pose_api.hpp defines common motion data structures for Controller Plugins using SI units:
| Data Structure | Description |
|---|---|
| PositionAPI | Position in meters. |
| QuaternionAPI | Orientation quaternion. |
| ConfDataAPI | Robot configuration data for determining the solution to reach a target point. |
| PoseAPI | Pose/coordinate frame; supports right multiply and inverse. |
| PointAPI | Point information; can represent Cartesian or joint points. |
| ZoneAPI | Zone including distance and percentage. |
| SpeedAPI | Speed including TCP speed, orientation speed, arm angle speed, percentage, etc. |
| LoadAPI | Load including mass, center of mass, and inertia. |
| TriggerAPI | Trajectory trigger; supports distance or time trigger. |
| ToolAPI | Tool coordinate frame and tool load. |
| WobjAPI | Work object coordinate frame, user coordinate frame, and work object load. |
const_data/ecat_api.hpp defines EtherCAT PDO/SDO data structures for use by the ethercat module.
utils: General Utilities
The utils module provides common utilities for plugin development.
File and JSON:
| Interface | Description |
|---|---|
| WriteBinaryToFileAPI() / ReadBinaryFromFileAPI() | Binary file write and read. |
| LoadFromFileAPI() / SaveToFileAPI() | JSON file read and save. |
| LoadFromStringAPI() / SaveToStringAPI() | JSON string parse and serialize. |
| SaveToStringInLineAPI() | Save JSON as line-oriented string. |
| CreateEmptyJsonFileAPI() | Create empty JSON file. |
| IsJsonFileAPI() | Check whether file is JSON. |
| GetPluginNameAPI() | Get current plugin name. |
Thread pool:
| Interface | Description |
|---|---|
| RunInThreadPoolAPI() | Run void function in thread pool. |
| RunInThreadPoolIntAPI() | Run function returning int in thread pool. |
Singleton:
| Interface / Macro | Description |
|---|---|
| SingletonBaseAPI<T> | Singleton base class template. |
| DECLARE_SINGLETON(type) | Declare singleton friend in class. |
| SINGLETON_INSTANCE(type) | Get singleton pointer. |
| INIT_SINGLETON(type) | Initialize singleton. |
Development Notes
- Plugin entry modules should auto-register through LAUNCH_MODULE or LAUNCH_MODULE_PRIORITY; avoid manual calls to undocumented initialization logic.
- Capabilities registered with the controller, such as RL commands, Hooks, Service, and log codes, should be placed in the appropriate lifecycle phase.
- Do not perform long blocking operations in synchronous Hooks, custom command execution functions, or motion callbacks; use the thread pool for time-consuming tasks.
- Use motion, power on/off, task space, and robot busy-state interfaces carefully; check controller state before calling.
- When reading/writing IO, registers, bus, and EtherCAT data, confirm names, addresses, data length, data type, and target architecture are consistent.
- Plugin logs should use the macros provided by the log module for easier filtering and troubleshooting by plugin.
- Plugin API version, controller version, and build architecture must match to avoid runtime load failures or inconsistent interface behavior.