README.md 5.48 KB

参数值解析器使用教程

概述

参数值解析器用于动态解析 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>();