Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
Z
zhmes-agecal
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
耿迪迪
zhmes-agecal
Commits
ff1c02a2
Commit
ff1c02a2
authored
Jan 05, 2026
by
wanghao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1 上料后 机械臂 回零 后 出现了一次 没有上电的操作,涉及到的 机械臂回零判断流程 优化。
2 实时数据 根据 托盘编号排序 3 如果设备号为空,则不设置各种状态信息,防止出现 没有板子的位置也报错,不能解绑的问题。
parent
9dc83746
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
134 additions
and
110 deletions
+134
-110
CalibrationResultEventHandler.java
...ong/system/netty/event/CalibrationResultEventHandler.java
+3
-1
NettyUdpServerHandler.java
...om/zehong/system/netty/handler/NettyUdpServerHandler.java
+105
-91
RobotArmCommandServiceImpl.java
...ehong/system/service/impl/RobotArmCommandServiceImpl.java
+17
-9
PalletDeviceBindingMapper.xml
...ain/resources/mapper/system/PalletDeviceBindingMapper.xml
+9
-9
No files found.
zhmes-agecal-system/src/main/java/com/zehong/system/netty/event/CalibrationResultEventHandler.java
View file @
ff1c02a2
...
...
@@ -93,6 +93,8 @@ public class CalibrationResultEventHandler {
for
(
PalletDeviceBinding
palletDeviceBinding
:
palletDeviceBindings
)
{
MesDeviceDomain
mesDeviceDomain
=
new
MesDeviceDomain
();
// 如果设备编号为空 则不处理改设备
if
(
StringUtils
.
isBlank
(
palletDeviceBinding
.
getDeviceCode
()))
continue
;
// 主板码
mesDeviceDomain
.
setMotherboardCode
(
palletDeviceBinding
.
getDeviceCode
());
// 浓度
...
...
@@ -499,4 +501,4 @@ public class CalibrationResultEventHandler {
this
.
calibrationValue
=
calibrationValue
;
}
}
}
\ No newline at end of file
}
zhmes-agecal-system/src/main/java/com/zehong/system/netty/handler/NettyUdpServerHandler.java
View file @
ff1c02a2
...
...
@@ -25,6 +25,7 @@ import java.util.Date;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.atomic.AtomicReference
;
import
java.util.concurrent.locks.ReentrantLock
;
/**
...
...
@@ -44,10 +45,6 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
private
static
final
SimpleDateFormat
DATE_FORMATTER
=
new
SimpleDateFormat
(
"yyyyMMdd"
);
private
static
final
SimpleDateFormat
TIME_FORMATTER
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
private
volatile
long
lastActivityTime
=
System
.
currentTimeMillis
();
/**
* 当前正在处理的指令信息
*/
private
final
Map
<
String
,
CommandExecution
>
currentCommands
=
new
ConcurrentHashMap
<>();
// 线程安全锁,确保文件写入安全
private
final
ReentrantLock
fileLock
=
new
ReentrantLock
();
...
...
@@ -59,11 +56,26 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
private
IRobotArmCommandService
robotArmCommandService
;
@Resource
private
ApplicationEventPublisher
eventPublisher
;
// 新增事件发布器
// 使用原子引用,确保状态变更的原子性
private
final
AtomicReference
<
CommandState
>
commandState
=
new
AtomicReference
<>(
CommandState
.
IDLE
);
// 当前执行的指令ID
private
volatile
Long
currentCommandId
=
null
;
private
enum
CommandState
{
IDLE
,
// 空闲
EXECUTING
,
// 执行中
COMPLETING
,
// 正在完成(防止重复)
ERROR
// 错误
}
/**
* 接收UDP消息
*/
@Override
protected
void
channelRead0
(
ChannelHandlerContext
ctx
,
DatagramPacket
packet
)
throws
Exception
{
protected
void
channelRead0
(
ChannelHandlerContext
ctx
,
DatagramPacket
packet
)
{
try
{
// 获取消息内容的字节缓冲区
ByteBuf
content
=
packet
.
content
();
...
...
@@ -93,9 +105,6 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
// 保存消息到文件
//saveMessageToFile(packet.sender().toString(), correctMessage);
// 处理消息逻辑
String
response
=
"服务器已收到UDP消息:"
+
correctMessage
;
// 记录最后活动时间
lastActivityTime
=
System
.
currentTimeMillis
();
// 判断消息类型并进行相应处理
...
...
@@ -106,26 +115,6 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
// 处理普通状态消息(原有逻辑)
handleNormalMessage
(
ctx
,
packet
,
correctMessage
);
}
// // 解析消息
// RobotArmMessageParser.RobotArmStatus status =
// RobotArmMessageParser.parseMessage(correctMessage);
//
// if (status != null) {
// // 处理状态消息
// processStatusMessage(status);
//
// // 检查是否为完全空闲状态
// if (status.isFullyIdle()) {
// handleFullyIdleState();
// }
// }
//
// // 回复客户端
// byte[] responseBytes = response.getBytes(StandardCharsets.UTF_8);
// ctx.writeAndFlush(new DatagramPacket(
// io.netty.buffer.Unpooled.copiedBuffer(responseBytes),
// packet.sender()));
}
catch
(
Exception
e
)
{
log
.
error
(
"处理UDP消息异常"
,
e
);
// 出现异常时发送故障状态
...
...
@@ -144,17 +133,11 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
packet
.
sender
()));
// 解析消息
RobotArmMessageParser
.
RobotArmStatus
status
=
RobotArmMessageParser
.
parseMessage
(
message
);
RobotArmMessageParser
.
RobotArmStatus
status
=
RobotArmMessageParser
.
parseMessage
(
message
);
if
(
status
!=
null
)
{
// 处理状态消息
processStatusMessage
(
status
);
// 检查是否为完全空闲状态
if
(
status
.
isFullyIdle
())
{
handleFullyIdleState
();
}
}
}
...
...
@@ -176,25 +159,54 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
}
/**
* 仅处理已完成的指令
* 仅处理已完成的指令
- 已修改为使用currentCommandId
*/
public
void
onlyCompleted
()
{
// 每次只能有一个指令正在执行
CommandExecution
execution
=
currentCommands
.
get
(
"127.0.0.1"
);
// 如果指令追踪为空,则可能是 刚启动,再去 查一下有没有正在执行的任务
if
(
execution
==
null
)
{
Long
commandId
=
null
;
// 优先从currentCommandId获取
if
(
currentCommandId
!=
null
)
{
commandId
=
currentCommandId
;
}
else
{
// 如果currentCommandId为空,从数据库查询正在执行的任务
List
<
RobotArmCommand
>
robotArmCommands
=
robotArmCommandService
.
selectTopRunningRobotArmCommands
();
if
(
robotArmCommands
!=
null
&&
!
robotArmCommands
.
isEmpty
())
{
// 注册指令跟踪
execution
=
new
CommandExecution
();
execution
.
commandId
=
robotArmCommands
.
get
(
0
).
getRobotArmCommandId
()
;
if
(
robotArmCommands
!=
null
&&
!
robotArmCommands
.
isEmpty
())
{
commandId
=
robotArmCommands
.
get
(
0
).
getRobotArmCommandId
();
// 如果找到了指令ID,更新currentCommandId
currentCommandId
=
commandId
;
}
}
if
(
execution
!=
null
)
{
robotArmCommandService
.
completeCommand
(
execution
.
commandId
);
currentCommands
.
remove
(
"127.0.0.1"
);
log
.
info
(
"指令完成: {}"
,
execution
.
commandId
);
if
(
commandId
!=
null
)
{
// 使用状态机完成指令
completeCommandWithStateMachine
(
commandId
);
}
}
/**
* 使用状态机完成指令
*/
private
void
completeCommandWithStateMachine
(
Long
commandId
)
{
// 检查当前状态和指令ID是否匹配
if
(
commandId
.
equals
(
currentCommandId
)
&&
commandState
.
compareAndSet
(
CommandState
.
EXECUTING
,
CommandState
.
COMPLETING
))
{
try
{
robotArmCommandService
.
completeCommand
(
commandId
);
log
.
info
(
"指令完成: {}"
,
commandId
);
// 清理状态
currentCommandId
=
null
;
commandState
.
set
(
CommandState
.
IDLE
);
// 处理待执行指令
handleFullyIdleState
();
}
catch
(
Exception
e
)
{
log
.
error
(
"指令完成失败: {}"
,
commandId
,
e
);
commandState
.
set
(
CommandState
.
ERROR
);
}
}
else
{
log
.
warn
(
"无法完成指令 {},当前状态: {}, 当前指令ID: {}"
,
commandId
,
commandState
.
get
(),
currentCommandId
);
}
}
...
...
@@ -207,45 +219,55 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
}
else
{
sendStatusToWebSocket
(
"error"
);
}
// 处理指令完成
// 处理指令完成逻辑 - 使用状态机防止重复
if
(
status
.
isFullyIdle
())
{
// 记录详细状态
log
.
debug
(
"机械臂状态: code={}, text={}, position=({},{},{},{})"
,
status
.
getCode
(),
status
.
getText
(),
status
.
getX
(),
status
.
getY
(),
status
.
getZ
(),
status
.
getR
());
CommandExecution
execution
=
currentCommands
.
get
(
"127.0.0.1"
);
// 如果指令追踪为空,则可能是 刚启动,再去 查一下有没有正在执行的任务
if
(
execution
==
null
)
{
List
<
RobotArmCommand
>
robotArmCommands
=
robotArmCommandService
.
selectTopRunningRobotArmCommands
();
if
(
robotArmCommands
!=
null
&&
!
robotArmCommands
.
isEmpty
())
{
// 注册指令跟踪
execution
=
new
CommandExecution
();
execution
.
commandId
=
robotArmCommands
.
get
(
0
).
getRobotArmCommandId
();
}
}
if
(
execution
!=
null
)
{
robotArmCommandService
.
completeCommand
(
execution
.
commandId
);
currentCommands
.
remove
(
"127.0.0.1"
);
log
.
info
(
"指令完成: {}"
,
execution
.
commandId
);
}
handleCompleteState
();
}
else
{
log
.
info
(
"status.isFullyIdle() = false"
);
}
}
private
void
handleCompleteState
()
{
// 原子地获取并清空当前指令ID
Long
commandIdToComplete
=
currentCommandId
;
if
(
commandIdToComplete
!=
null
)
{
// 尝试将状态从 EXECUTING 转为 COMPLETING
if
(
commandState
.
compareAndSet
(
CommandState
.
EXECUTING
,
CommandState
.
COMPLETING
))
{
try
{
// 完成指令
robotArmCommandService
.
completeCommand
(
commandIdToComplete
);
log
.
info
(
"指令完成: {}"
,
commandIdToComplete
);
// 清空当前指令
currentCommandId
=
null
;
// 状态转为空闲
commandState
.
set
(
CommandState
.
IDLE
);
// 处理待执行指令
handleFullyIdleState
();
}
catch
(
Exception
e
)
{
log
.
error
(
"指令完成失败: {}"
,
commandIdToComplete
,
e
);
commandState
.
set
(
CommandState
.
ERROR
);
}
}
}
else
{
// 没有当前指令,直接处理待执行
handleFullyIdleState
();
}
}
/**
* 记录当前执行的指令
*/
public
void
registerCommandExecution
(
Long
commandId
)
{
CommandExecution
execution
=
new
CommandExecution
();
execution
.
c
ommandId
=
commandId
;
execution
.
startTime
=
System
.
currentTimeMillis
(
);
// 每次只能有一个正在执行中的,所以先暂时用使用了127.0.0.1
currentCommands
.
put
(
"127.0.0.1"
,
execution
);
log
.
info
(
"注册指令跟踪: {}"
,
commandId
);
if
(
commandState
.
compareAndSet
(
CommandState
.
IDLE
,
CommandState
.
EXECUTING
))
{
currentC
ommandId
=
commandId
;
log
.
info
(
"注册指令跟踪: {}"
,
commandId
);
}
else
{
throw
new
IllegalStateException
(
"机械臂当前状态不能执行新指令"
);
}
}
...
...
@@ -288,11 +310,8 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
IdleStateEvent
event
=
(
IdleStateEvent
)
evt
;
if
(
event
.
state
()
==
IdleState
.
ALL_IDLE
)
{
log
.
info
(
"UDP服务器超过规定时间未收到数据"
);
long
now
=
System
.
currentTimeMillis
();
long
idleDuration
=
now
-
lastActivityTime
;
// 如果长时间空闲(>2秒)
if
(
idleDuration
>
20000
)
{
handleLongIdleState
();
}
...
...
@@ -301,12 +320,14 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
super
.
userEventTriggered
(
ctx
,
evt
);
}
}
private
void
handleLongIdleState
()
{
// 检查是否有超时的指令
// 如果当前没有执行中的指令,尝试处理待执行指令
if
(
currentCommands
.
isEmpty
())
{
private
void
handleLongIdleState
()
{
// 检查当前是否有执行中的指令(使用currentCommandId)
if
(
currentCommandId
==
null
)
{
handleFullyIdleState
();
}
else
{
log
.
info
(
"当前有指令正在执行中,指令ID: {}"
,
currentCommandId
);
}
}
/**
...
...
@@ -320,13 +341,6 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
}
}
// 添加指令执行状态
private
static
class
CommandExecution
{
Long
commandId
;
long
startTime
;
}
/**
* 将消息保存到本地文件
*
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/service/impl/RobotArmCommandServiceImpl.java
View file @
ff1c02a2
...
...
@@ -36,12 +36,12 @@ import javax.annotation.Resource;
/**
* 机械臂指令Service业务层处理
*
*
* @author zehong
* @date 2025-08-04
*/
@Service
public
class
RobotArmCommandServiceImpl
implements
IRobotArmCommandService
public
class
RobotArmCommandServiceImpl
implements
IRobotArmCommandService
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
RobotArmCommandServiceImpl
.
class
);
...
...
@@ -89,6 +89,10 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
}
}
/**
* 机械臂空闲状态下 需要执行的待执行的指令
*/
@Override
@Transactional
public
void
processPendingCommands
()
{
...
...
@@ -336,6 +340,10 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
return
0
;
}
/**
* 完成指令
* @param commandId c
*/
@Override
@Transactional
public
void
completeCommand
(
Long
commandId
)
{
...
...
@@ -346,7 +354,6 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
log
.
info
(
"command != null && \"2\".equals(command.getStatus()"
);
// 发送上电指令
try
{
String
storeyCode
=
command
.
getStoreyCode
();
String
equitmentCode
;
int
registerOffset
;
...
...
@@ -361,6 +368,7 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
log
.
info
(
"tEquipmentInfo != null"
);
String
powerOutageIp
=
tEquipmentInfo
.
getfPowerOutageIp
();
Integer
powerOutagePort
=
tEquipmentInfo
.
getfPowerOutagePort
();
log
.
info
(
"powerOutageIp: {}, powerOutagePort: {},command.getType:{}"
,
powerOutageIp
,
powerOutagePort
,
command
.
getType
());
if
(
StringUtils
.
isNotBlank
(
powerOutageIp
)
&&
powerOutagePort
!=
null
)
{
if
(
"0"
.
equals
(
command
.
getType
()))
{
eventPublisher
.
publishEvent
(
new
CheckPowerOnCommandEvent
(
...
...
@@ -415,7 +423,7 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
/**
* 查询机械臂指令
*
*
* @param robotArmCommandId 机械臂指令ID
* @return 机械臂指令
*/
...
...
@@ -427,7 +435,7 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
/**
* 查询机械臂指令列表
*
*
* @param robotArmCommand 机械臂指令
* @return 机械臂指令
*/
...
...
@@ -475,7 +483,7 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
/**
* 新增机械臂指令
*
*
* @param robotArmCommand 机械臂指令
* @return 结果
*/
...
...
@@ -578,7 +586,7 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
/**
* 修改机械臂指令
*
*
* @param robotArmCommand 机械臂指令
* @return 结果
*/
...
...
@@ -606,7 +614,7 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
/**
* 批量删除机械臂指令
*
*
* @param robotArmCommandIds 需要删除的机械臂指令ID
* @return 结果
*/
...
...
@@ -620,7 +628,7 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
/**
* 删除机械臂指令信息
*
*
* @param robotArmCommandId 机械臂指令ID
* @return 结果
*/
...
...
zhmes-agecal-system/src/main/resources/mapper/system/PalletDeviceBindingMapper.xml
View file @
ff1c02a2
...
...
@@ -3,7 +3,7 @@
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.zehong.system.mapper.PalletDeviceBindingMapper"
>
<resultMap
type=
"PalletDeviceBinding"
id=
"PalletDeviceBindingResult"
>
<result
property=
"palletDeviceBindingId"
column=
"f_pallet_device_binding_id"
/>
<result
property=
"trayId"
column=
"f_tray_id"
/>
...
...
@@ -101,7 +101,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select>
<select
id=
"selectPalletDeviceBindingList"
parameterType=
"PalletDeviceBinding"
resultMap=
"PalletDeviceBindingResult"
>
<include
refid=
"selectPalletDeviceBindingVo"
/>
<where>
<where>
<if
test=
"trayId != null "
>
and palDeviceBinding.f_tray_id = #{trayId}
</if>
<if
test=
"deviceCode != null and deviceCode != ''"
>
and palDeviceBinding.f_device_code like concat('%',#{deviceCode},'%')
</if>
<if
test=
"fTrayCode != null and fTrayCode != ''"
>
and trayInfo.f_tray_code like concat('%',#{fTrayCode},'%')
</if>
...
...
@@ -114,18 +114,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"createTime != null "
>
and palDeviceBinding.f_create_time = #{createTime}
</if>
<if
test=
"status != null and status != '' "
>
and palDeviceBinding.f_status = #{status}
</if>
</where>
order by trayInfo.f_tray_code ,palDeviceBinding.f_
index
asc
order by trayInfo.f_tray_code ,palDeviceBinding.f_
number
asc
</select>
<select
id=
"getAllExcludeUnbindingTimeByTrayId"
parameterType=
"long"
resultMap=
"PalletDeviceBindingResult"
>
<include
refid=
"selectPalletDeviceBindingVo"
/>
where palDeviceBinding.f_tray_id = #{trayId}
order by palDeviceBinding.f_
index
asc
order by palDeviceBinding.f_
number
asc
</select>
<select
id=
"listByTrayCode"
parameterType=
"string"
resultMap=
"PalletDeviceBindingResult"
>
<include
refid=
"selectPalletDeviceBindingVo"
/>
where trayInfo.f_tray_code = #{trayCode}
</select>
<select
id=
"selectPalletDeviceBindingById"
parameterType=
"Long"
resultMap=
"PalletDeviceBindingResult"
>
<include
refid=
"selectPalletDeviceBindingVo"
/>
where palDeviceBinding.f_pallet_device_binding_id = #{palletDeviceBindingId}
...
...
@@ -327,7 +327,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"simCardStatus != null"
>
f_sim_card_status = #{simCardStatus},
</if>
<if
test=
"networkStatus != null"
>
f_network_status = #{networkStatus},
</if>
</trim>
where f_pallet_device_binding_id = #{palletDeviceBindingId}
where f_pallet_device_binding_id = #{palletDeviceBindingId}
and f_device_code is not null
</update>
<update
id=
"batchUpdateDeviceCode"
parameterType=
"list"
>
<foreach
collection=
"palletDeviceBindingList"
item=
"item"
index=
"index"
separator=
";"
>
...
...
@@ -350,7 +350,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"item.calibrationConcentration != null"
>
f_calibration_concentration = #{item.calibrationConcentration},
</if>
<if
test=
"item.calibrationConcentrationStatus != null"
>
f_calibration_concentration_status = #{item.calibrationConcentrationStatus},
</if>
</trim>
where f_pallet_device_binding_id = #{item.palletDeviceBindingId}
where f_pallet_device_binding_id = #{item.palletDeviceBindingId}
and f_device_code is not null
</foreach>
</update>
<update
id=
"batchUpdateDeviceCodeAndUnbindingTime"
parameterType=
"list"
>
...
...
@@ -430,9 +430,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</delete>
<delete
id=
"deletePalletDeviceBindingByIds"
parameterType=
"String"
>
delete from t_pallet_device_binding where f_pallet_device_binding_id in
delete from t_pallet_device_binding where f_pallet_device_binding_id in
<foreach
item=
"palletDeviceBindingId"
collection=
"array"
open=
"("
separator=
","
close=
")"
>
#{palletDeviceBindingId}
</foreach>
</delete>
</mapper>
\ No newline at end of file
</mapper>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment