wanshenmean
5 天以前 b0327633d7d0c19693a4e577d1e17b3b22e8274e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
 
namespace WIDESEAWCS_Tasks
{
    /// <summary>
    /// 机械手 Socket 通信状态数据类
    /// </summary>
    /// <remarks>
    /// 该类用于在 Redis 缓存中存储机械手的实时状态,包括位置、任务、手臂对象等信息。
    /// 所有属性均设计为线程安全更新,通过 <see cref="RobotStateManager"/> 的版本控制机制来防止并发覆盖。
    /// </remarks>
    public class RobotSocketState
    {
        /// <summary>
        /// 机械手的 IP 地址,作为缓存键的唯一标识
        /// </summary>
        public string IPAddress { get; set; } = string.Empty;
 
        /// <summary>
        /// 版本号,用于乐观并发控制
        /// </summary>
        /// <remarks>
        /// 每次修改状态时更新为 DateTime.UtcNow.Ticks。
        /// <see cref="RobotStateManager"/> 使用此字段实现乐观锁,防止并发更新时旧值覆盖新值。
        /// </remarks>
        public long Version { get; set; } = DateTime.UtcNow.Ticks;
 
        /// <summary>
        /// 是否已订阅消息事件标志
        /// </summary>
        /// <remarks>
        /// 确保每个客户端只启动一次消息处理循环,避免重复订阅导致的消息重复处理。
        /// </remarks>
        public bool IsEventSubscribed { get; set; }
 
        /// <summary>
        /// 机械手运行模式
        /// </summary>
        /// <remarks>
        /// 1: 手动模式
        /// 2: 自动模式
        /// 当 RobotRunMode == 2 且 RobotControlMode == 1 时,系统进入自动控制状态。
        /// </remarks>
        public int? RobotRunMode { get; set; }
 
        /// <summary>
        /// 机械手控制模式
        /// </summary>
        /// <remarks>
        /// 1: 客户端控制
        /// 2: 未知/其他
        /// 与 RobotRunMode 配合判断机器人的当前控制状态。
        /// </remarks>
        public int? RobotControlMode { get; set; }
 
        /// <summary>
        /// 机械手手臂抓取对象状态
        /// </summary>
        /// <remarks>
        /// 0: 无物料(手臂空闲)
        /// 1: 有物料(已抓取货物)
        /// 用于判断机器人是否可以执行下一步动作。
        /// </remarks>
        public int? RobotArmObject { get; set; }
 
        /// <summary>
        /// 机械手设备基础信息
        /// </summary>
        /// <remarks>
        /// 包含设备的 DeviceCode、DeviceName、IPAddress 等基础信息。
        /// 在状态初始化时从 JobDetail.JobDataMap 获取并缓存。
        /// </remarks>
        public RobotCraneDevice? RobotCrane { get; set; }
 
        /// <summary>
        /// 机械手初始化完成回到待机位
        /// </summary>
        /// <remarks>
        /// 可能的值:
        /// - "Homed": 已回零
        /// - "Homing": 回零中
        /// </remarks>
        public string? Homed { get; set; }
 
        /// <summary>
        /// 机械手当前正在执行的动作
        /// </summary>
        /// <remarks>
        /// 可能的值:
        /// - "Picking": 取货中
        /// - "Putting": 放货中
        /// - "PickFinished": 取货完成
        /// - "PutFinished": 放货完成
        /// - "AllPickFinished": 全部取货完成
        /// - "AllPutFinished": 全部放货完成
        /// </remarks>
        public string? CurrentAction { get; set; }
 
        /// <summary>
        /// 机械手当前运行状态
        /// </summary>
        /// <remarks>
        /// 可能的值:
        /// - "Homing": 回零中
        /// - "Homed": 已回零
        /// - "Running": 运行中
        /// - "Pausing": 暂停中
        /// - "Warming": 预热中
        /// - "Emstoping": 急停中
        /// </remarks>
        public string? OperStatus { get; set; }
 
        /// <summary>
        /// 最近一次取货完成的位置数组
        /// </summary>
        /// <remarks>
        /// 数组中的每个元素代表一个电池位置编号。
        /// 用于记录取货动作涉及的货位,供后续组盘/拆盘操作使用。
        /// </remarks>
        public int[]? LastPickPositions { get; set; }
 
        /// <summary>
        /// 最近一次放货完成的位置数组
        /// </summary>
        /// <remarks>
        /// 数组中的每个元素代表一个电池位置编号。
        /// 用于记录放货动作涉及的货位。
        /// </remarks>
        public int[]? LastPutPositions { get; set; }
 
        /// <summary>
        /// 电池/货位条码列表
        /// </summary>
        /// <remarks>
        /// 在组盘操作时用于记录生成的托盘条码。
        /// 每个条码格式为 "TRAY" + 日期 + 时间 + 随机数。
        /// </remarks>
        public List<string> CellBarcode { get; set; } = new List<string>();
 
        /// <summary>
        /// 机械手当前正在执行的任务
        /// </summary>
        /// <remarks>
        /// 当任务下发到机器人后,该字段保存任务详情。
        /// 任务类型包括:组盘(500)、换盘(510)、拆盘(520)。
        /// </remarks>
        public Dt_RobotTask? CurrentTask { get; set; }
 
        /// <summary>
        /// 是否需要执行拆盘任务
        /// </summary>
        /// <remarks>
        /// 当任务类型为 SplitPallet (520) 时设为 true。
        /// 拆盘任务将电池从托盘上取下并逐个放置到目标位置。
        /// </remarks>
        public bool IsSplitPallet { get; set; }
 
        /// <summary>
        /// 是否需要执行组盘任务
        /// </summary>
        /// <remarks>
        /// 当任务类型为 GroupPallet (500) 或 ChangePallet (510) 时设为 true。
        /// 组盘任务将多个电池组合到同一个托盘上。
        /// </remarks>
        public bool IsGroupPallet { get; set; }
 
        /// <summary>
        /// 机器人已处理的任务总数
        /// </summary>
        /// <remarks>
        /// 累计记录机器人已完成处理的电池/货物数量。
        /// 当达到 MaxTaskTotalNum (48) 时,不再下发新任务。
        /// </remarks>
        public int RobotTaskTotalNum { get; set; }
    }
}