Time Manipulator Plugin
Plugin Overview
The time_manipulator_plugin provides a time_manipulator
executor that enables time scaling functionality. It also registers an RPC based on protobuf protocol definition, offering some management interfaces for the time_manipulator
executor. Note that time_manipulator_plugin does not provide any communication backend, so this plugin is typically used in combination with RPC backends from other communication plugins, such as the http RPC backend in net_plugin.
The plugin configuration items are as follows:
Node |
Type |
Optional |
Default |
Description |
---|---|---|---|---|
service_name |
string |
Yes |
“” |
RPC Service Name. If empty, uses the default value generated from the protocol |
Here’s a simple configuration example combining time_manipulator_plugin with the http RPC backend from net_plugin:
aimrt:
plugin:
plugins:
- name: net_plugin
path: ./libaimrt_net_plugin.so
options:
thread_num: 4
http_options:
listen_ip: 127.0.0.1
listen_port: 50080
- name: time_manipulator_plugin
path: ./libaimrt_time_manipulator_plugin.so
rpc:
backends:
- type: http
servers_options:
- func_name: "(pb:/aimrt.protocols.time_manipulator_plugin.*)"
enable_backends: [http]
time_manipulator Executor
The time_manipulator
executor is a speed-adjustable executor based on a timing wheel implementation, typically used in simulation scenarios with timing tasks that don’t require high timing precision. It runs a timing wheel in a separate thread while also supporting task delegation to other executors. All its configuration items are as follows:
Node |
Type |
Optional |
Default |
Description |
---|---|---|---|---|
bind_executor |
string |
Required |
“” |
Bound executor |
dt_us |
unsigned int |
Yes |
100000 |
Timing wheel tick interval in microseconds |
init_ratio |
double |
Yes |
1.0 |
Initial time ratio |
wheel_size |
unsigned int array |
Yes |
[100, 360] |
Sizes of timing wheels |
thread_sched_policy |
string |
Yes |
“” |
Scheduling policy for timing wheel thread |
thread_bind_cpu |
unsigned int array |
Yes |
[] |
CPU binding configuration for timing wheel thread |
use_system_clock |
bool |
Yes |
false |
Whether to use std::system_clock (default uses std::steady_clock) |
Usage notes:
bind_executor
configures the bound executor for task execution when time is reached.Must bind to another executor;
Thread safety matches the bound executor;
Throws an exception during initialization if the bound executor doesn’t exist;
dt_us
is a timing wheel algorithm parameter representing tick interval. Larger intervals mean lower scheduling precision but better CPU resource efficiency.init_ratio
is the initial time ratio (default 1.0), meaning real-time speed.wheel_size
is another timing wheel parameter representing wheel sizes. Default[1000, 600]
means two wheels with 1000 and 600 ticks respectively. With 1ms tick time, the first wheel covers 1s and the second 10min. Generally, ensure possible timing ranges fall within the wheels.thread_sched_policy
andthread_bind_cpu
refer to thread binding configuration in Common Information.use_system_clock
determines whether to use std::system_clock (default false uses std::steady_clock). Note that with std::system_clock, executor time synchronizes with system time and may be affected by external adjustments.
The time_manipulator
executor’s time_ratio
parameter is a floating-point value with these meanings:
time_ratio
> 1.0: Fast-forward attime_ratio
times real speed;time_ratio
= 1.0: Matches real-time speed;0.0 <
time_ratio
< 1.0: Slow motion attime_ratio
times real speed;time_ratio
= 0.0: Paused;Negative
time_ratio
: Equivalent to 0.0 (time cannot reverse);
The time_manipulator
executor synchronizes with real time once during process startup and executor initialization, then maintains independent time progression based on the time ratio. As documented in Executor, the time ratio mainly affects the executor’s Now
method return value and timing for ExecuteAt
/ExecuteAfter
methods.
Here’s a simple example:
aimrt:
plugin:
plugins:
- name: time_manipulator_plugin
path: ./libaimrt_time_manipulator_plugin.so
executor:
executors:
- name: real_work_thread_pool
type: simple_thread
- name: time_schedule_executor
type: time_manipulator
options:
bind_executor: real_work_thread_pool
dt_us: 1000
init_ratio: 2.0
wheel_size: [1000, 3600]
TimeManipulatorService
The time_manipulator.proto protocol file defines a TimeManipulatorService
with these interfaces:
SetTimeRatio: Set time ratio;
Pause: Pause;
GetTimeRatio: Get current time ratio;
SetTimeRatio
The SetTimeRatio
interface sets the time ratio for a time_manipulator
executor, defined as:
message SetTimeRatioReq {
string executor_name = 1;
double time_ratio = 2;
}
message CommonRsp {
double time_ratio = 1;
uint32 code = 2;
string msg = 3;
}
service TimeManipulatorService {
// ...
rpc SetTimeRatio(SetTimeRatioReq) returns (CommonRsp);
// ...
}
Here’s an example using curl with the http RPC backend from net_plugin:
curl -i \
-H 'content-type:application/json' \
-X POST 'http://127.0.0.1:50080/rpc/aimrt.protocols.time_manipulator_plugin.TimeManipulatorService/SetTimeRatio' \
-d '{"executor_name": "time_schedule_executor", "time_ratio": 2.0}'
This command sets the time ratio to 2.0 for the time_schedule_executor
. If successful, the command returns:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 34
{"time_ratio":2,"code":0,"msg":""}
Pause
The Pause
interface pauses a time_manipulator
executor, defined as:
message PauseReq {
string executor_name = 1;
}
message CommonRsp {
double time_ratio = 1;
uint32 code = 2;
string msg = 3;
}
service TimeManipulatorService {
// ...
rpc Pause(PauseReq) returns (CommonRsp);
// ...
}
Here’s an example using curl with the http RPC backend from net_plugin:
curl -i \
-H 'content-type:application/json' \
-X POST 'http://127.0.0.1:50080/rpc/aimrt.protocols.time_manipulator_plugin.TimeManipulatorService/Pause' \
-d '{"executor_name": "time_schedule_executor"}'
This command pauses the time_schedule_executor
. If successful, it returns:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 34
{"time_ratio":0,"code":0,"msg":""}
GetTimeRatio
The GetTimeRatio
interface retrieves the current time ratio of a time_manipulator
executor, defined as:
message GetTimeRatioReq {
string executor_name = 1;
}
message CommonRsp {
double time_ratio = 1;
uint32 code = 2;
string msg = 3;
}
service TimeManipulatorService {
// ...
rpc GetTimeRatio(GetTimeRatioReq) returns (CommonRsp);
// ...
}
Here’s an example using curl with the http RPC backend from net_plugin:
curl -i \
-H 'content-type:application/json' \
-X POST 'http://127.0.0.1:50080/rpc/aimrt.protocols.time_manipulator_plugin.TimeManipulatorService/GetTimeRatio' \
-d '{"executor_name": "time_schedule_executor"}'
This command retrieves the current time ratio of time_schedule_executor
. If successful, it returns:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 34
{"time_ratio":1,"code":0,"msg":""}