编辑 | blame | 历史 | 原始文档

堆垛机出库任务 TargetAddress 输送线站台空闲检查 设计文档

1. 背景与目标

StackerCraneTaskSelector.TrySelectOutboundTask 方法中,当前只检查出库站台的 NextAddress 是否可用(IsOutTaskStationAvailable)。需求:增加对 TargetAddress 输送线站台的空闲状态检查。只有当 TargetAddress 输送线站台空闲(CV_State == 2)时,才认为该出库任务真正可选。

2. 设计方案

2.1 新增私有方法

StackerCraneTaskSelector 类中新增方法 IsTargetAddressConveyorStationAvailable

/// <summary>
/// 判断 TargetAddress 输送线站台是否空闲
/// </summary>
/// <param name="task">出库任务</param>
/// <returns>站台空闲返回 true,否则返回 false</returns>
private bool IsTargetAddressConveyorStationAvailable([NotNull] Dt_Task task)
{
    // 确定任务类型
    int taskType = task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty
        ? StackerCraneConst.EmptyPalletTaskType
        : task.TaskType;

    // 通过路由查找 TargetAddress 对应的设备信息
    Dt_Router? router = _routerService.QueryNextRoute(task.Roadway, task.TargetAddress, taskType);
    if (router == null)
    {
        QuartzLogHelper.LogWarn(_logger, "IsTargetAddressConveyorStationAvailable:未找到 TargetAddress 路由信息,TargetAddress: {TargetAddress},任务号: {TaskNum}",
            $"IsTargetAddressConveyorStationAvailable:未找到 TargetAddress 路由信息,TargetAddress: {task.TargetAddress}", task.Roadway, task.TargetAddress, task.TaskNum);
        return false;
    }

    // 查找输送线设备
    IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == router.ChildPosiDeviceCode);
    if (device == null)
    {
        QuartzLogHelper.LogWarn(_logger, "IsTargetAddressConveyorStationAvailable:未找到输送线设备,ChildPosiDeviceCode: {ChildPosiDeviceCode},任务号: {TaskNum}",
            $"IsTargetAddressConveyorStationAvailable:未找到输送线设备,ChildPosiDeviceCode: {router.ChildPosiDeviceCode}", task.Roadway, router.ChildPosiDeviceCode, task.TaskNum);
        return false;
    }

    // 转换为输送线设备
    CommonConveyorLine conveyorLine = (CommonConveyorLine)device;

    // 读取 CV_State,CV_State == 2 表示空闲
    byte cvState = conveyorLine.GetValue<ConveyorLineStatus, byte>(ConveyorLineStatus.CV_State, task.TargetAddress);
    bool isAvailable = cvState == 2;
    QuartzLogHelper.LogInfo(_logger, "IsTargetAddressConveyorStationAvailable:TargetAddress: {TargetAddress},CV_State: {CV_State},是否空闲: {IsAvailable},任务号: {TaskNum}",
        $"IsTargetAddressConveyorStationAvailable:TargetAddress: {task.TargetAddress},CV_State: {cvState},是否空闲: {isAvailable}", task.Roadway, task.TargetAddress, cvState, isAvailable, task.TaskNum);

    return isAvailable;
}

2.2 调用点修改

TrySelectOutboundTask 方法中,在 return IsOutTaskStationAvailable(taskAfterTransferCheck) ? taskAfterTransferCheck : null; 之前插入:

// 判断 TargetAddress 输送线站台是否空闲
if (!IsTargetAddressConveyorStationAvailable(taskAfterTransferCheck))
{
    return null;
}

2.3 流程图

出库任务进入 TrySelectOutboundTask
    ↓
移库检查(_transferCheck)
    ↓
是否移库任务?是 → 返回任务
    ↓(否)
IsOutTaskStationAvailable(NextAddress 出库站台) → 不可用 → 返回 null
    ↓(可用)
IsTargetAddressConveyorStationAvailable(TargetAddress 输送线站台) → 不可用 → 返回 null
    ↓(可用,即 CV_State == 2)
返回任务

3. 涉及的命名空间

新增方法需要 using:
- WIDESEAWCS_QuartzJob.ConveyorLine.Enum.ConveyorLineStatusConveyorLineStatus.CV_State 枚举)
- WIDESEAWCS_Model.Models.Dt_Router(路由实体)
- WIDESEAWCS_Core.Storage(设备存储)

4. 风险与约束

  • CV_State == 2 表示空闲是业务约定,需与 PLC 侧协议保持一致
  • 如设备未连接或协议配置缺失,GetValue 会抛出异常,当前设计让异常向上传播,调用方通过 try-catch 兜底