README.md
参数值解析器使用教程
概述
参数值解析器用于动态解析 VDA5050 动作参数值,支持从不同数据源获取值,并支持算术表达式运算。
支持的参数来源类型
| ParameterSourceType | 说明 | 示例 |
|---|---|---|
| Constant (1) | 固定常量值 | "floor" |
| Task (2) | 从任务对象获取 | TaskCode |
| Robot (3) | 从机器人对象获取 | RobotCode |
| Path (4) | 从路径对象获取 | 预留 |
| Node (5) | 从节点对象获取 | NodeCode |
| Edge (6) | 从边对象获取 | EdgeCode |
| Context (7) | 表达式计算 | ${Node.LayerHeight} * 2 + 50 |
数据库配置示例
1. 常量值参数
INSERT INTO action_parameter_definitions
(param_id, action_config_id, parameter_name, parameter_value_type, parameter_source_type, default_value)
VALUES
('...', '...', 'stationType', 1, 1, 'floor');
2. 任务属性参数
INSERT INTO action_parameter_definitions
(param_id, action_config_id, parameter_name, parameter_value_type, parameter_source_type, parameter_source_path)
VALUES
('...', '...', 'loadType', 1, 2, 'TaskType');
3. 机器人属性参数
INSERT INTO action_parameter_definitions
(param_id, action_config_id, parameter_name, parameter_value_type, parameter_source_type, parameter_source_path, default_value)
VALUES
('...', '...', 'robotCode', 1, 3, 'RobotCode', 'UNKNOWN');
4. 节点属性参数
INSERT INTO action_parameter_definitions
(param_id, action_config_id, parameter_name, parameter_value_type, parameter_source_type, parameter_source_path)
VALUES
('...', '...', 'nodeId', 1, 5, 'NodeCode');
5. 表达式参数(算术运算)
-- 举升高度 = 层高 * 层数 + 固定偏移量
INSERT INTO action_parameter_definitions
(param_id, action_config_id, parameter_name, parameter_value_type, parameter_source_type, parameter_source_path, default_value)
VALUES
('...', '...', 'liftHeight', 3, 7, '${Node.LayerHeight} * ${Node.LayerCount} + 50', '0');
6. 表达式参数(字符串拼接)
-- 货物ID = 任务编码_机器人编码
INSERT INTO action_parameter_definitions
(param_id, action_config_id, parameter_name, parameter_value_type, parameter_source_type, parameter_source_path)
VALUES
('...', '...', 'loadId', 1, 7, '${Task.TaskCode}_${Robot.RobotCode}');
表达式语法
变量引用
使用 ${Source.Path} 格式引用变量:
-
${Task.TaskCode}- 任务编码 -
${Task.Priority}- 任务优先级 -
${Robot.RobotCode}- 机器人编码 -
${Robot.BatteryLevel}- 电池电量 -
${Node.NodeCode}- 节点编码 -
${Node.X}- 节点X坐标 -
${Edge.EdgeCode}- 边编码
嵌套属性
支持点号分隔的嵌套属性访问:
-
${Robot.MapNode.NodeCode}- 机器人当前节点编码 -
${Task.StartNode.X}- 任务起点X坐标
算术运算
支持 +, -, *, /, % 和括号:
${Node.LayerHeight} * ${Node.LayerCount} + 50
(${Robot.HeightMax} - ${Robot.HeightMin}) / 2
${Node.X} * 1000
代码使用示例
1. 注入解析器工厂
public class MyService
{
private readonly IParameterValueResolverFactory _resolverFactory;
public MyService(IParameterValueResolverFactory resolverFactory)
{
_resolverFactory = resolverFactory;
}
}
2. 构建上下文并解析参数
// 构建解析上下文
var context = new ParameterContext
{
Task = new AgvTask { TaskCode = "T001", Priority = 1 },
Robot = new Robot { RobotCode = "AGV01", BatteryLevel = 80 },
Node = new MapNode { NodeCode = "N001", X = 100, Y = 200 }
};
// 解析所有参数
var parameters = _resolverFactory.ResolveAll(actionConfig.Parameters, context);
// 结果示例:
// [
// { Key: "stationType", Value: "floor" },
// { Key: "loadType", Value: "Pickup" },
// { Key: "robotCode", Value: "AGV01" },
// { Key: "liftHeight", Value: "650" } // 300 * 2 + 50 = 650
// ]
3. 解析单个参数
var value = _resolverFactory.Resolve(parameterDefinition, context);
完整业务示例
取货动作参数配置
| 参数名 | 来源类型 | 来源路径/值 | 说明 |
|---|---|---|---|
| stationType | Constant | floor | 站点类型固定值 |
| loadType | Task | TaskType | 从任务获取货物类型 |
| height | Context | ${Node.LayerHeight} * ${Node.LayerCount} + 50 |
计算举升高度 |
| nodeId | Node | NodeCode | 当前节点编码 |
| loadId | Context | ${Task.TaskCode}_${Robot.RobotCode} |
组合货物ID |
解析结果
假设上下文数据:
- Task:
{ TaskCode: "T001", TaskType: "Pickup" } - Robot:
{ RobotCode: "AGV01" } - Node:
{ NodeCode: "N001", LayerHeight: 300, LayerCount: 2 }
解析后的 VDA5050 参数:
[
{ "key": "stationType", "value": "floor" },
{ "key": "loadType", "value": "Pickup" },
{ "key": "height", "value": "650" },
{ "key": "nodeId", "value": "N001" },
{ "key": "loadId", "value": "T001_AGV01" }
]
扩展新的解析器
如需支持新的数据源类型,实现 IParameterValueResolver 接口:
public class CustomResolver : IParameterValueResolver
{
public ParameterSourceType SourceType => ParameterSourceType.Custom;
public object? Resolve(ActionParameterDefinition definition, ParameterContext context)
{
// 自定义解析逻辑
return "custom_value";
}
}
然后在 DependencyInjectionInstaller 中注册:
services.AddScoped<IParameterValueResolver, CustomResolver>();