更新通讯适配器
Some checks failed
Gradle Build / build (push) Has been cancelled

This commit is contained in:
wait
2025-03-31 10:48:46 +08:00
parent ece8013fec
commit 17c28a5a7f
27 changed files with 1395 additions and 27 deletions

View File

@@ -15,4 +15,12 @@ public interface GuestUserCredentials {
* The default/guest password.
*/
String PASSWORD = "xyz";
/**
* 主机IP
*/
String IP = "192.168.0.106";
/**
* 内核开放端口
*/
Integer PORT = 1099;
}

View File

@@ -41,5 +41,17 @@ public interface LoopbackAdapterConstants {
* The key of the vehicle property that specifies the maximum decceleration of a vehicle.
*/
String PROPKEY_DECELERATION = "loopback:deceleration";
/**
* AGV 控制器授权码
*/
String AGV_AUTHORIZE_CODE = "AGV:AUTHORIZE_CODE";
/**
* AGV IP
*/
String AGV_IP = "AGV:IP";
/**
* AGV 端口
*/
String AGV_PORT = "AGV:PORT";
}

View File

@@ -0,0 +1,39 @@
package org.opentcs.kc.udp.Service;
import org.opentcs.kc.udp.agv.param.AgvEvent;
import org.opentcs.kc.udp.agv.param.rsp.RcvEventPackage;
/**
* @author xzh
* @date 2025/2/21
* @desc 命令基类
*/
public class BaseCommand {
public static String byteToHex(byte b) {
// 将byte转换为无符号整数
int unsignedByte = b & 0xFF;
// 使用Integer.toHexString方法转换为十六进制字符串
String hexString = Integer.toHexString(unsignedByte);
// 如果字符串长度为1需要在前面补0
if (hexString.length() == 1) {
return "0" + hexString;
}
return hexString;
}
public static void printInfo(AgvEvent agvEvent){
System.out.println("sended transationId : "+agvEvent.getTransationIdString());
for (byte b:agvEvent.toBytes().getBody()){
System.out.print(byteToHex(b)+" ");
}
}
public static void printInfo(RcvEventPackage rcv){
for (byte b: rcv.getDataBytes()){
System.out.print(byteToHex(b)+" ");
}
}
}

View File

@@ -0,0 +1,39 @@
package org.opentcs.kc.udp.Service;
import org.opentcs.kc.udp.agv.param.AgvEvent;
import org.opentcs.kc.udp.agv.param.AgvEventConstant;
import org.opentcs.kc.udp.agv.param.rsp.RcvEventPackage;
import org.opentcs.kc.udp.io.UDPClient;
/**
* @author xzh
* @date 2025/2/21
* @desc 确认位置 0x1F
*/
public class ConfirmRelocation extends BaseCommand{
/**
* decs: 确认机器人位置
* 指令0x1F
* author: caixiang
* date: 2025/1/17 16:25
* */
public static AgvEvent confirmInitialPosition() {
AgvEvent agvEvent = new AgvEvent(AgvEventConstant.CommandCode_CONFIRM_ROBOT_POSITION);
return agvEvent;
}
public static void commnd() {
//0x1F(确认初始位置)
AgvEvent agvEvent = confirmInitialPosition();
printInfo(agvEvent);
RcvEventPackage rcv = UDPClient.localAGV.send(agvEvent);
if(rcv.isOk()){
System.out.println("0x1F ok");
}else {
System.out.println();
System.out.println("0x1F fail");
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
}
}
}

View File

@@ -0,0 +1,139 @@
package org.opentcs.kc.udp.Service;
import org.opentcs.kc.common.byteutils.ByteUtils;
import org.opentcs.kc.udp.agv.param.AgvEvent;
import org.opentcs.kc.udp.agv.param.AgvEventConstant;
import org.opentcs.kc.udp.agv.param.function.navigation.Action;
import org.opentcs.kc.udp.agv.param.function.navigation.ActionSet;
import org.opentcs.kc.udp.agv.param.function.navigation.NavigationParam;
import org.opentcs.kc.udp.agv.param.function.navigation.Path;
import org.opentcs.kc.udp.agv.param.function.navigation.Point;
import org.opentcs.kc.udp.agv.param.rsp.RcvEventPackage;
import org.opentcs.kc.udp.io.UDPClient;
public class HybridNavigation extends BaseCommand{
/**
* 测试模式true=开启测试false=关闭测试
* 测试模式因orderName为String类型数据无法转换为Integer
*/
private static boolean TEST_MODEL = false;
/**
* 订单ID
* 订单的唯一标识。用于标识多个任务KEY是否属于同一个订单。机器人单次只能接收同一订单ID的任务直至订单结束调度可下发新的订单ID订单ID从1开始累加每次+1。
* 注同一订单ID支持不停车更新导航。
*/
private static Integer orderID = 0;
/**
* 任务ID
* 任务的唯一标识。与订单ID绑定从1开始当同一订单下发新的资源时加1订单ID发生改变任务KEY需要重新计数。
*/
private static Integer taskKey;
/**
* 序列号
* 用于定位点在整个任务中的位置。目的是区分同一个点ID是否在一个任务中出现多次。从0开始偶数递增例如0->2->4->6……
*/
private static Integer pointSerialNum = 0;
/**
* 用于定位段在整个任务中的位置。目的是区分同一个段ID是否在一个任务中出现多次。从1开始奇数递增例如1->3->5->7……
*/
private static Integer pathSerialNum = 1;
/**
* decs: 导航控制
* 指令0xAE
* author: caixiang
* date: 2025/1/17 16:25
* */
public static AgvEvent navigationControl(Integer sourcePoint, Integer destinationPoint, Integer pathID, String operation) {
AgvEvent agvEvent = new AgvEvent(AgvEventConstant.CommandCode_QUERY_ROBOT_STATUS);
//TODO 构建
Integer orderId = orderID;
// Integer orderId = 1;
//构建point
Action[] pointActions1 = new Action[]{
new Action(ActionSet.stop0x01, (byte) 0x00, 1, ActionSet.stop0x01_paramsize, ActionSet.stop0x01(orderId, (byte) 0x01))
//,new Action()... 每一个point 可以绑定一个或者多个 action
};
Action[] pointActions2 = new Action[]{
new Action(ActionSet.stop0x01, (byte) 0x00, 1, ActionSet.stop0x01_paramsize, ActionSet.stop0x01(orderId, (byte) 0x01))
};
// Action[] pointActions3 = new Action[]{
// new Action(ActionSet.stop0x01, (byte) 0x00, 1, ActionSet.stop0x01_paramsize, ActionSet.stop0x01(orderId, (byte) 0x01))
// };
Integer oldPointSerialNum = pointSerialNum;
pointSerialNum += 2;
Point[] points = new Point[]{
new Point(oldPointSerialNum, sourcePoint, 1f, (byte)0x00, ByteUtils.usintTo1Byte(pointActions1.length),pointActions1),
new Point(pointSerialNum, destinationPoint, 1f, (byte)0x00, ByteUtils.usintTo1Byte(pointActions2.length),pointActions2)
// new Point(4, 3, 1f, (byte)0x00, ByteUtils.usintTo1Byte(pointActions3.length),pointActions3)
};
//构建path
Action[] pathActions1 = new Action[]{
new Action(ActionSet.stop0x01, (byte) 0x00, 1, ActionSet.stop0x01_paramsize, ActionSet.stop0x01(orderId, (byte) 0x01))
//,new Action()... 每一个path 可以绑定一个或者多个 action
};
// Action[] pathActions2 = new Action[]{
// new Action(ActionSet.stop0x01, (byte) 0x00, 1, ActionSet.stop0x01_paramsize, ActionSet.stop0x01(orderId, (byte) 0x01))
// };
Path[] paths = new Path[]{
new Path(pathSerialNum,pathID,1f,(byte)0x00,(byte)0x00,ByteUtils.usintTo1Byte(pathActions1.length),5f,1f,pathActions1) ,
// new Path(3,2,1f,(byte)0x00,(byte)0x00,ByteUtils.usintTo1Byte(pathActions2.length),5f,1f,pathActions2) ,
};
NavigationParam navigationParam = new NavigationParam(orderID,taskKey,ByteUtils.usintTo1Byte(points.length),ByteUtils.usintTo1Byte(points.length-1),points,paths);
agvEvent.setBody(navigationParam.toBytes());
return agvEvent;
}
/**
*
* @param orderName 订单ID
* @param sourcePoint 下发起点
* @param destinationPoint 下发终点
* @param operation 执行操作
*/
public static void command(String orderName, String sourcePoint, String destinationPoint, String operation) {
if (TEST_MODEL) {
return;
}
Integer newOrderName = Integer.parseInt(orderName);
Integer newSourcePoint = Integer.parseInt(sourcePoint);
Integer newDestinationPoint = Integer.parseInt(destinationPoint);
//拼接起点终点字符串转为Integer类型获取唯一pathID
Integer pathID = Integer.parseInt(sourcePoint + destinationPoint);
if (!orderID.equals(newOrderName)) {
//切换订单重置参数
initParams(newOrderName);
}
//0xAE(导航控制导航点控制)
AgvEvent agvEvent = navigationControl(newSourcePoint, newDestinationPoint, pathID, operation);
printInfo(agvEvent);
RcvEventPackage rcv = UDPClient.localAGV.send(agvEvent);
if(rcv.isOk()){
System.out.println("0xAE ok");
}else {
System.out.println();
System.out.println("0xAE fail");
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
}
}
/**
* 初始化参数
* @param newOrderName 新的订单ID
*/
private static void initParams(Integer newOrderName) {
orderID = newOrderName;
taskKey = 1;
pointSerialNum = 0;
pathSerialNum = 1;
}
}

View File

@@ -0,0 +1,46 @@
package org.opentcs.kc.udp.Service;
import org.opentcs.kc.udp.agv.param.AgvEvent;
import org.opentcs.kc.udp.agv.param.AgvEventConstant;
import org.opentcs.kc.udp.agv.param.function.x14.RobotSetPosition;
import org.opentcs.kc.udp.agv.param.rsp.RcvEventPackage;
import org.opentcs.kc.udp.io.UDPClient;
/**
* @author xzh
* @date 2025/2/21
* @desc 手动定位 0x14
*/
public class ManualPosition extends BaseCommand{
public static AgvEvent manualLocation(double agvX, double agvY, double agvAngle) {
AgvEvent agvEvent = new AgvEvent(AgvEventConstant.CommandCode_ROBOT_SET_POSITION);
RobotSetPosition robotSetPosition = new RobotSetPosition(agvX, agvY, agvAngle);
byte[] bytes = robotSetPosition.toBytes();
agvEvent.setBody(bytes);
return agvEvent;
}
public static void command(double agvX, double agvY, double agvAngle) {
//0x14(手动定位)
AgvEvent agvEvent = manualLocation(agvX, agvY, agvAngle);
printInfo(agvEvent);
RcvEventPackage rcv = UDPClient.localAGV.send(agvEvent);
if(rcv.isOk()){
System.out.println();
System.out.println("received "+ "isok:"+rcv.isOk()+" dataBytes:");
printInfo(rcv);
if(rcv.isOk()){
//get and parse value
System.out.println("0x14 ok");
}else {
System.out.println("0x14 failed");
}
}else {
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
throw new RuntimeException("0x14 failed");
}
}
}

View File

@@ -0,0 +1,48 @@
package org.opentcs.kc.udp.Service;
import org.opentcs.kc.udp.agv.param.AgvEvent;
import org.opentcs.kc.udp.agv.param.AgvEventConstant;
import org.opentcs.kc.udp.agv.param.function.x17.QueryRobotRunStatusRsp;
import org.opentcs.kc.udp.agv.param.rsp.RcvEventPackage;
import org.opentcs.kc.udp.io.UDPClient;
/**
* @author xzh
* @date 2025/2/21
* @desc 获取AGV运行状态
*/
public class QryRobotRunStatus extends BaseCommand{
/**
* decs: 查询机器人运行状态
* 指令0x17
* author: caixiang
* date: 2025/1/17 16:25
* */
public static AgvEvent queryRobotRunStatus() {
AgvEvent agvEvent = new AgvEvent(AgvEventConstant.CommandCode_QUERY_ROBOT_RUN_STATUS);
return agvEvent;
}
public static QueryRobotRunStatusRsp command() {
//0x17(查询机器人运行状态)
AgvEvent agvEvent = queryRobotRunStatus();
printInfo(agvEvent);
RcvEventPackage rcv = UDPClient.localAGV.send(agvEvent);
if(rcv.isOk()){
//QueryCargoStatusRsp queryCargoStatusRsp = new QueryCargoStatusRsp(rcv.getDataBytes());
QueryRobotRunStatusRsp queryRobotRunStatusRsp = new QueryRobotRunStatusRsp(rcv.getDataBytes());
System.out.println(queryRobotRunStatusRsp.toString());
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
for (byte b:rcv.getValue()){
System.out.print(byteToHex(b)+" ");
}
return queryRobotRunStatusRsp;
}else {
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
throw new RuntimeException("0x17 fail");
}
}
}

View File

@@ -0,0 +1,48 @@
package org.opentcs.kc.udp.Service;
import org.opentcs.kc.udp.agv.param.AgvEvent;
import org.opentcs.kc.udp.agv.param.AgvEventConstant;
import org.opentcs.kc.udp.agv.param.function.af.QueryRobotStatusRsp;
import org.opentcs.kc.udp.agv.param.rsp.RcvEventPackage;
import org.opentcs.kc.udp.io.UDPClient;
/**
* @author xzh
* @date 2025/2/21
* @desc 查询机器人状态
*/
public class QryRobotStatus
extends BaseCommand {
/**
* decs: 查询机器人状态
* 指令0xAF
* author: caixiang
* date: 2025/1/17 16:25
* */
public static AgvEvent queryStatus() {
AgvEvent agvEvent = new AgvEvent(AgvEventConstant.CommandCode_QUERY_ROBOT_STATUS);
return agvEvent;
}
public static QueryRobotStatusRsp command() {
//0xAF(查询机器人状态)
AgvEvent agvEvent = queryStatus();
printInfo(agvEvent);
RcvEventPackage rcv = UDPClient.localAGV.send(agvEvent);
if(rcv.isOk()){
QueryRobotStatusRsp queryRobotStatusRsp = new QueryRobotStatusRsp(rcv.getDataBytes());
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
return queryRobotStatusRsp;
// for (byte b:rcv.getValue()){
// System.out.print(byteToHex(b)+" ");
// }
}else {
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
throw new RuntimeException("0xAF fail");
}
}
}

View File

@@ -0,0 +1,74 @@
package org.opentcs.kc.udp.Service;
import static java.util.Objects.requireNonNull;
import java.util.ArrayList;
import java.util.List;
import org.opentcs.kc.udp.agv.param.AgvEvent;
import org.opentcs.kc.udp.agv.param.AgvEventConstant;
import org.opentcs.kc.udp.agv.param.function.b0.QueryCargoStatusRsp;
import org.opentcs.kc.udp.agv.param.function.b1.SubscribeInfo;
import org.opentcs.kc.udp.agv.param.function.b1.SubscribeParam;
import org.opentcs.kc.udp.agv.param.function.b1.SubscribeRsp;
import org.opentcs.kc.udp.agv.param.rsp.RcvEventPackage;
import org.opentcs.kc.udp.io.UDPClient;
/**
* @author xzh
* @date 2025/2/21
* @desc 订阅载货状态
*/
public class SubCargoStatus extends BaseCommand{
/**
* decs: 下发订阅信息
* 指令0xB1
* author: caixiang
* date: 2025/1/17 16:25
* */
public static AgvEvent issueSubscribe() {
List<SubscribeInfo> subscribeInfoList = new ArrayList<>();
// SubscribeInfo subscribeInfo = new SubscribeInfo(new byte[]{(byte)0xaf,(byte)0x00}, (short) 100,1000);
SubscribeInfo subscribeInfo = new SubscribeInfo(new byte[]{(byte)0xb0,(byte)0x00}, (short) 100,1000);
subscribeInfoList.add(subscribeInfo);
SubscribeParam subscribeParam = new SubscribeParam(subscribeInfoList);
AgvEvent agvEvent = new AgvEvent(AgvEventConstant.CommandCode_ISSUE_SUBSCRIPTION,subscribeParam.toBytes());
return agvEvent;
}
public static void command()
{
// 0xB1(订阅信息)
AgvEvent agvEvent = issueSubscribe();
printInfo(agvEvent);
//todo 订阅参数构建完毕 去写 回调部分
RcvEventPackage rcv = UDPClient.localAGV.send(agvEvent);
if(rcv.isOk()){
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
SubscribeRsp subscribeRsp = new SubscribeRsp(rcv.getDataBytes());
if(subscribeRsp.isOk()){
//...
}else {
//...
}
}else {
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
}
}
//订阅执行操作
public void subscribe0xB0Operate(String name,QueryCargoStatusRsp queryCargoStatusRsp)
{
// Vehicle vehicle = vehicleService.fetchObject(Vehicle.class, name);
//修改载货状态
if (queryCargoStatusRsp.isCargo == 0) {
//未载货
} else if (queryCargoStatusRsp.isCargo == 1) {
//载货
}
}
}

View File

@@ -0,0 +1,57 @@
package org.opentcs.kc.udp.Service;
import java.util.ArrayList;
import java.util.List;
import org.opentcs.kc.udp.agv.param.AgvEvent;
import org.opentcs.kc.udp.agv.param.AgvEventConstant;
import org.opentcs.kc.udp.agv.param.function.b1.SubscribeInfo;
import org.opentcs.kc.udp.agv.param.function.b1.SubscribeParam;
import org.opentcs.kc.udp.agv.param.function.b1.SubscribeRsp;
import org.opentcs.kc.udp.agv.param.rsp.RcvEventPackage;
import org.opentcs.kc.udp.io.UDPClient;
/**
* @author xzh
* @date 2025/2/21
* @desc 订阅机器人状态
*/
public class SubRobotStatue extends BaseCommand {
/**
* decs: 下发订阅信息
* 指令0xB1
* author: caixiang
* date: 2025/1/17 16:25
* */
public static AgvEvent issueSubscribe() {
List<SubscribeInfo> subscribeInfoList = new ArrayList<>();
SubscribeInfo subscribeInfo = new SubscribeInfo(new byte[]{(byte)0xaf,(byte)0x00}, (short) 100,1000);
// SubscribeInfo subscribeInfo = new SubscribeInfo(new byte[]{(byte)0xb0,(byte)0x00}, (short) 100,1000);
subscribeInfoList.add(subscribeInfo);
SubscribeParam subscribeParam = new SubscribeParam(subscribeInfoList);
AgvEvent agvEvent = new AgvEvent(AgvEventConstant.CommandCode_ISSUE_SUBSCRIPTION,subscribeParam.toBytes());
return agvEvent;
}
public static void command() {
// 0xB1(订阅信息)
AgvEvent agvEvent = issueSubscribe();
printInfo(agvEvent);
//todo 订阅参数构建完毕 去写 回调部分
RcvEventPackage rcv = UDPClient.localAGV.send(agvEvent);
if(rcv.isOk()){
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
SubscribeRsp subscribeRsp = new SubscribeRsp(rcv.getDataBytes());
if(subscribeRsp.isOk()){
//...
}else {
//...
}
}else {
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
}
}
}

View File

@@ -0,0 +1,65 @@
package org.opentcs.kc.udp.Service;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import org.opentcs.kc.common.byteutils.ByteUtils;
import org.opentcs.kc.udp.agv.param.AgvEvent;
import org.opentcs.kc.udp.agv.param.AgvEventConstant;
import org.opentcs.kc.udp.agv.param.function.write.WriteParam;
import org.opentcs.kc.udp.agv.param.function.write.WriteStrValue;
import org.opentcs.kc.udp.agv.param.function.write.WriteValueMember;
import org.opentcs.kc.udp.agv.param.rsp.RcvEventPackage;
import org.opentcs.kc.udp.io.UDPClient;
/**
* @author xzh
* @date 2025/2/21
* @desc 切换自动模式
*/
public class SwitchAutomaticMode extends BaseCommand{
/**
* decs: write操作
* 指令0x03
* author: caixiang
* date: 2025/1/17 16:25
* */
public static AgvEvent writeValue() {
AgvEvent agvEvent = new AgvEvent(AgvEventConstant.CommandCode_WRITE);
List<WriteValueMember> valueMemberList = new ArrayList<>();
WriteValueMember valueMember1 = new WriteValueMember(Short.valueOf("1"),Short.valueOf("4"), ByteUtils.uintToBytes(3, ByteOrder.LITTLE_ENDIAN));
valueMemberList.add(valueMember1);
List<WriteStrValue> strValueList = new ArrayList<>();
WriteStrValue strValue = new WriteStrValue("TestRW", 1, valueMemberList);
strValueList.add(strValue);
WriteParam param = new WriteParam(1,strValueList );
agvEvent.setBody(param.toBytes());
return agvEvent;
}
public static void command() {
//0x03(切换手自动)
AgvEvent agvEvent = writeValue();
printInfo(agvEvent);
RcvEventPackage rcv = UDPClient.localAGV.send(agvEvent);
if(rcv.isOk()){
System.out.println();
System.out.println("received "+ "isok:"+rcv.isOk()+" dataBytes:");
printInfo(rcv);
if(rcv.isOk()){
//get and parse value
System.out.println("write ok");
}else {
System.out.println("write failed");
}
}else {
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
}
}
}

View File

@@ -0,0 +1,65 @@
package org.opentcs.kc.udp.Service;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import org.opentcs.kc.common.byteutils.ByteUtils;
import org.opentcs.kc.udp.agv.param.AgvEvent;
import org.opentcs.kc.udp.agv.param.AgvEventConstant;
import org.opentcs.kc.udp.agv.param.function.write.WriteParam;
import org.opentcs.kc.udp.agv.param.function.write.WriteStrValue;
import org.opentcs.kc.udp.agv.param.function.write.WriteValueMember;
import org.opentcs.kc.udp.agv.param.rsp.RcvEventPackage;
import org.opentcs.kc.udp.io.UDPClient;
/**
* @author xzh
* @date 2025/2/21
* @desc 切换手动模式
*/
public class SwitchManualMode extends BaseCommand{
/**
* decs: write操作
* 指令0x03
* author: caixiang
* date: 2025/1/17 16:25
* */
public static AgvEvent writeValue() {
AgvEvent agvEvent = new AgvEvent(AgvEventConstant.CommandCode_WRITE);
List<WriteValueMember> valueMemberList = new ArrayList<>();
WriteValueMember valueMember1 = new WriteValueMember(Short.valueOf("0"),Short.valueOf("4"), ByteUtils.uintToBytes(3, ByteOrder.LITTLE_ENDIAN));
valueMemberList.add(valueMember1);
List<WriteStrValue> strValueList = new ArrayList<>();
WriteStrValue strValue = new WriteStrValue("TestRW", 1, valueMemberList);
strValueList.add(strValue);
WriteParam param = new WriteParam(1,strValueList );
agvEvent.setBody(param.toBytes());
return agvEvent;
}
public static void command() {
//0x03(切换手自动)
AgvEvent agvEvent = writeValue();
printInfo(agvEvent);
RcvEventPackage rcv = UDPClient.localAGV.send(agvEvent);
if(rcv.isOk()){
System.out.println();
System.out.println("received "+ "isok:"+rcv.isOk()+" dataBytes:");
printInfo(rcv);
if(rcv.isOk()){
//get and parse value
System.out.println("write ok");
}else {
System.out.println("write failed");
}
}else {
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
}
}
}

View File

@@ -4,6 +4,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import java.net.InetSocketAddress;
import org.opentcs.kc.common.Package;
import org.opentcs.kc.syn.SendedList;
import org.opentcs.kc.udp.agv.param.rsp.RcvEventPackage;
@@ -60,7 +61,12 @@ public class AgvUdpDecode extends SimpleChannelInboundHandler<DatagramPacket> {
byte commandCode = body[21];
if(body[18]==(byte)0x00 && body[19]==(byte)0x00){
if(commandCode == (byte)0xAF ){
//获取响应IP
InetSocketAddress sender = msg.sender();
String hostAddress = sender.getAddress().getHostAddress();
if(commandCode == (byte)0xAF ){
client.subscribe0xAF(new RcvEventPackage(body[22],body));
}else if(commandCode == (byte)0xB0){
client.subscribe0xB0(new RcvEventPackage(body[22],body));

View File

@@ -53,7 +53,7 @@ public class QueryRobotRunStatusRsp {
//累计运行时间(单位 ms,8个字节
private double cumulativeRunTime;
//机器人定位状态,1个字节
private byte robotLocalizationState;
public byte robotLocalizationState;
//保留3个字节
private byte[] retain3;
//地图数量U32,4个字节

View File

@@ -9,6 +9,12 @@ import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import java.net.InetSocketAddress;
import java.util.Set;
import org.opentcs.access.KernelServicePortal;
import org.opentcs.access.rmi.KernelServicePortalBuilder;
import org.opentcs.common.GuestUserCredentials;
import org.opentcs.components.kernel.services.VehicleService;
import org.opentcs.data.model.Vehicle;
import org.opentcs.kc.common.Package;
import org.opentcs.kc.common.byteutils.ByteUtil;
import org.opentcs.kc.syn.AsyncFuture;
@@ -29,9 +35,14 @@ import org.slf4j.LoggerFactory;
public enum UDPClient {
//如果要配置多个链接, local1 local2 .... 这样排下去好了
localAGV("agv1","192.168.0.211",17804,55678),
localAGV("1","192.168.0.211",17804,55678),
//local("127.0.0.1",502,true),
;
// 服务端地址+端口
private String SERVICE_HOST = "192.168.0.123";
private Integer SERVICE_PORT = 1099;
private String name;
private String host;
//默认 0 port
@@ -132,35 +143,88 @@ public enum UDPClient {
}
public void subscribe0xB0(RcvEventPackage rcv){
if(name.equals("agv1")){
QueryCargoStatusRsp queryCargoStatusRsp = new QueryCargoStatusRsp(rcv.getDataBytes());
System.out.println();
System.out.println("received subscribe 0xB0 List : "+ "isok:"+rcv.isOk());
for (byte b:rcv.getValue()){
System.out.print(byteToHex(b)+" ");
}
}else if(name.equals("agv2")){
//....
if (rcv.isOk()) {
if(name.equals("1")){
this.achieveSub0xB0(name, rcv);
}else if(name.equals("2")){
this.achieveSub0xB0(name, rcv);
}
} else {
System.out.println();
System.out.println("subscribe0xB0 received transationId : "+ "isok:"+rcv.isOk());
}
}
public void subscribe0xAF(RcvEventPackage rcv){
if(name.equals("agv1")){
if(rcv.isOk()){
QueryRobotStatusRsp queryRobotStatusRsp = new QueryRobotStatusRsp(rcv.getDataBytes());
System.out.println();
System.out.println("received subscribe 0xAF List : "+ "isok:"+rcv.isOk());
for (byte b:rcv.getValue()){
System.out.print(byteToHex(b)+" ");
}
}else {
System.out.println();
System.out.println("received transationId : "+ "isok:"+rcv.isOk());
}
}else if(name.equals("agv2")){
//....
if (rcv.isOk()) {
if (name.equals("1")) {
this.achieveSub0xAF(name, rcv);
} else if (name.equals("2")) {
this.achieveSub0xAF(name, rcv);
}
} else {
System.out.println();
System.out.println("subscribe0xAF received transationId : "+ "isok:"+rcv.isOk());
}
}
/**
* 0xAF上报信息传入通讯适配器
* @param vehicleName 车辆名称
* @param rcv 响应数据
*/
private void achieveSub0xAF(String vehicleName ,RcvEventPackage rcv){
QueryRobotStatusRsp queryRobotStatusRsp = new QueryRobotStatusRsp(rcv.getDataBytes());
System.out.println();
System.out.println("received subscribe 0xAF List : "+ "isok:"+rcv.isOk());
for (byte b:rcv.getValue()){
System.out.print(byteToHex(b)+" ");
}
KernelServicePortal servicePortal = new KernelServicePortalBuilder(GuestUserCredentials.USER, GuestUserCredentials.PASSWORD).build();
servicePortal.login(SERVICE_HOST, SERVICE_PORT);
VehicleService vehicleService = servicePortal.getVehicleService();
Vehicle vehicle = vehicleService.fetchObject(Vehicle.class, vehicleName);
//将AGV控制器上报信息传入通讯适配器
vehicleService.sendCommAdapterMessage(vehicle.getReference(), queryRobotStatusRsp);
servicePortal.logout();
}
/**
* 0xB0上报信息传入通讯适配器
* @param vehicleName 车辆名称
* @param rcv 响应数据
*/
private void achieveSub0xB0(String vehicleName ,RcvEventPackage rcv){
QueryCargoStatusRsp queryCargoStatusRsp = new QueryCargoStatusRsp(rcv.getDataBytes());
System.out.println();
System.out.println("received subscribe 0xB0 List : "+ "isok:"+rcv.isOk());
for (byte b:rcv.getValue()){
System.out.print(byteToHex(b)+" ");
}
KernelServicePortal servicePortal = new KernelServicePortalBuilder(GuestUserCredentials.USER, GuestUserCredentials.PASSWORD).build();
servicePortal.login(SERVICE_HOST, SERVICE_PORT);
VehicleService vehicleService = servicePortal.getVehicleService();
Vehicle vehicle = vehicleService.fetchObject(Vehicle.class, vehicleName);
//将AGV控制器上报信息传入通讯适配器
vehicleService.sendCommAdapterMessage(vehicle.getReference(), queryCargoStatusRsp);
servicePortal.logout();
}
public static void printInfo(AgvEvent agvEvent){
System.out.println("sended transationId : "+agvEvent.getTransationIdString());
for (byte b:agvEvent.toBytes().getBody()){

View File

@@ -9,11 +9,18 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.opentcs.access.KernelServicePortal;
import org.opentcs.access.rmi.KernelServicePortalBuilder;
import org.opentcs.components.kernel.services.PlantModelService;
import org.opentcs.components.kernel.services.VehicleService;
import org.opentcs.data.model.Vehicle;
/**
* Tests for {@link SameThreadExecutorService}.
@@ -79,4 +86,40 @@ class SameThreadExecutorServiceTest {
verify(task).call();
}
@Test
void testVehicle(){
//获取车辆对象代码
KernelServicePortal servicePortal = new KernelServicePortalBuilder(GuestUserCredentials.USER,GuestUserCredentials.PASSWORD).build();
servicePortal.login(GuestUserCredentials.IP, GuestUserCredentials.PORT);
// servicePortal.getPlantModelService().up
PlantModelService plantModelService = servicePortal.getPlantModelService();
VehicleService vehicleService = servicePortal.getVehicleService();
Set<Vehicle> vehicles = vehicleService.fetchObjects(Vehicle.class);
for (Vehicle vehicle : vehicles) {
System.out.println("vehicle:"+vehicle);
}
}
@Test
void testRemoveVehicle(){
HashMap<String, Object> map = new HashMap<>();
int energy = 54;
map.put("energy", energy);
long positionX = -100;
map.put("positionX", positionX);
long positionY = 6510;
map.put("positionY", positionY);
double positionAngle = 0.0;
map.put("positionAngle", positionAngle);
//向车辆对应的通讯适配器发送消息
KernelServicePortal servicePortal = new KernelServicePortalBuilder(GuestUserCredentials.USER,GuestUserCredentials.PASSWORD).build();
servicePortal.login(GuestUserCredentials.IP, GuestUserCredentials.PORT);
VehicleService vehicleService = servicePortal.getVehicleService();
Vehicle vehicle = vehicleService.fetchObject(Vehicle.class, "2");
vehicleService.sendCommAdapterMessage(vehicle.getReference(), map);
}
}