feat(agv): 添加AGV固定距离平移功能

- 定义AgvTranslateCommand消息结构,包含请求和反馈
- 添加AgvTranslationMode枚举,支持里程和定位两种距离参考模式
- 定义AgvTranslation消息,包含距离、速度和平移模式参数
- 在AgvService服务中添加translate RPC方法
- 生成Java gRPC客户端和服务端代码实现
- 更新protobuf描述符以包含新的平移命令定义
This commit is contained in:
lixiaolong 2026-08-11 15:16:15 +08:00
parent c51823801d
commit 1543a6fb9c
8 changed files with 3266 additions and 141 deletions

View File

@ -90,6 +90,9 @@ public class EdgeAgvServiceImpl implements EdgeAgvService {
edgeCommonVO.getRobotId(), AgvServiceGrpc.AgvServiceBlockingStub.class); edgeCommonVO.getRobotId(), AgvServiceGrpc.AgvServiceBlockingStub.class);
AgvCommand.AgvNavigateToStationCommand.Request request = AgvCommand.AgvNavigateToStationCommand.Request.newBuilder() AgvCommand.AgvNavigateToStationCommand.Request request = AgvCommand.AgvNavigateToStationCommand.Request.newBuilder()
.setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId())) .setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId()))
.setOptions(AgvUtils.AgvMotionOptions.newBuilder()
.setAsynchronous(true)
.build())
.setStationId(stationId) .setStationId(stationId)
.build(); .build();
executeGrpcCall(() -> stub.navigateToStation(request)); executeGrpcCall(() -> stub.navigateToStation(request));

View File

@ -639,6 +639,37 @@ public final class AgvServiceGrpc {
return getStopMappingMethod; return getStopMappingMethod;
} }
private static volatile io.grpc.MethodDescriptor<cmvr.api.AgvCommand.AgvTranslateCommand.Request,
cmvr.api.AgvCommand.AgvTranslateCommand.Feedback> getTranslateMethod;
@io.grpc.stub.annotations.RpcMethod(
fullMethodName = SERVICE_NAME + '/' + "translate",
requestType = cmvr.api.AgvCommand.AgvTranslateCommand.Request.class,
responseType = cmvr.api.AgvCommand.AgvTranslateCommand.Feedback.class,
methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
public static io.grpc.MethodDescriptor<cmvr.api.AgvCommand.AgvTranslateCommand.Request,
cmvr.api.AgvCommand.AgvTranslateCommand.Feedback> getTranslateMethod() {
io.grpc.MethodDescriptor<cmvr.api.AgvCommand.AgvTranslateCommand.Request, cmvr.api.AgvCommand.AgvTranslateCommand.Feedback> getTranslateMethod;
if ((getTranslateMethod = AgvServiceGrpc.getTranslateMethod) == null) {
synchronized (AgvServiceGrpc.class) {
if ((getTranslateMethod = AgvServiceGrpc.getTranslateMethod) == null) {
AgvServiceGrpc.getTranslateMethod = getTranslateMethod =
io.grpc.MethodDescriptor.<cmvr.api.AgvCommand.AgvTranslateCommand.Request, cmvr.api.AgvCommand.AgvTranslateCommand.Feedback>newBuilder()
.setType(io.grpc.MethodDescriptor.MethodType.UNARY)
.setFullMethodName(generateFullMethodName(SERVICE_NAME, "translate"))
.setSampledToLocalTracing(true)
.setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
cmvr.api.AgvCommand.AgvTranslateCommand.Request.getDefaultInstance()))
.setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
cmvr.api.AgvCommand.AgvTranslateCommand.Feedback.getDefaultInstance()))
.setSchemaDescriptor(new AgvServiceMethodDescriptorSupplier("translate"))
.build();
}
}
}
return getTranslateMethod;
}
/** /**
* Creates a new async stub that supports all call types for the service * Creates a new async stub that supports all call types for the service
*/ */
@ -893,6 +924,16 @@ public final class AgvServiceGrpc {
io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStopMappingMethod(), responseObserver); io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStopMappingMethod(), responseObserver);
} }
/**
* <pre>
* 按指定速度平移固定距离。成功返回仅表示控制器已接受命令。
* </pre>
*/
public void translate(cmvr.api.AgvCommand.AgvTranslateCommand.Request request,
io.grpc.stub.StreamObserver<cmvr.api.AgvCommand.AgvTranslateCommand.Feedback> responseObserver) {
io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getTranslateMethod(), responseObserver);
}
@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
.addMethod( .addMethod(
@ -1035,6 +1076,13 @@ public final class AgvServiceGrpc {
cmvr.api.Common.CommandHeader.Request, cmvr.api.Common.CommandHeader.Request,
cmvr.api.Common.CommandHeader.Feedback>( cmvr.api.Common.CommandHeader.Feedback>(
this, METHODID_STOP_MAPPING))) this, METHODID_STOP_MAPPING)))
.addMethod(
getTranslateMethod(),
io.grpc.stub.ServerCalls.asyncUnaryCall(
new MethodHandlers<
cmvr.api.AgvCommand.AgvTranslateCommand.Request,
cmvr.api.AgvCommand.AgvTranslateCommand.Feedback>(
this, METHODID_TRANSLATE)))
.build(); .build();
} }
} }
@ -1278,6 +1326,17 @@ public final class AgvServiceGrpc {
io.grpc.stub.ClientCalls.asyncUnaryCall( io.grpc.stub.ClientCalls.asyncUnaryCall(
getChannel().newCall(getStopMappingMethod(), getCallOptions()), request, responseObserver); getChannel().newCall(getStopMappingMethod(), getCallOptions()), request, responseObserver);
} }
/**
* <pre>
* 按指定速度平移固定距离。成功返回仅表示控制器已接受命令。
* </pre>
*/
public void translate(cmvr.api.AgvCommand.AgvTranslateCommand.Request request,
io.grpc.stub.StreamObserver<cmvr.api.AgvCommand.AgvTranslateCommand.Feedback> responseObserver) {
io.grpc.stub.ClientCalls.asyncUnaryCall(
getChannel().newCall(getTranslateMethod(), getCallOptions()), request, responseObserver);
}
} }
/** /**
@ -1500,6 +1559,16 @@ public final class AgvServiceGrpc {
return io.grpc.stub.ClientCalls.blockingUnaryCall( return io.grpc.stub.ClientCalls.blockingUnaryCall(
getChannel(), getStopMappingMethod(), getCallOptions(), request); getChannel(), getStopMappingMethod(), getCallOptions(), request);
} }
/**
* <pre>
* 按指定速度平移固定距离。成功返回仅表示控制器已接受命令。
* </pre>
*/
public cmvr.api.AgvCommand.AgvTranslateCommand.Feedback translate(cmvr.api.AgvCommand.AgvTranslateCommand.Request request) {
return io.grpc.stub.ClientCalls.blockingUnaryCall(
getChannel(), getTranslateMethod(), getCallOptions(), request);
}
} }
/** /**
@ -1729,6 +1798,17 @@ public final class AgvServiceGrpc {
return io.grpc.stub.ClientCalls.futureUnaryCall( return io.grpc.stub.ClientCalls.futureUnaryCall(
getChannel().newCall(getStopMappingMethod(), getCallOptions()), request); getChannel().newCall(getStopMappingMethod(), getCallOptions()), request);
} }
/**
* <pre>
* 按指定速度平移固定距离。成功返回仅表示控制器已接受命令。
* </pre>
*/
public com.google.common.util.concurrent.ListenableFuture<cmvr.api.AgvCommand.AgvTranslateCommand.Feedback> translate(
cmvr.api.AgvCommand.AgvTranslateCommand.Request request) {
return io.grpc.stub.ClientCalls.futureUnaryCall(
getChannel().newCall(getTranslateMethod(), getCallOptions()), request);
}
} }
private static final int METHODID_GET_RUNTIME_STATE = 0; private static final int METHODID_GET_RUNTIME_STATE = 0;
@ -1751,6 +1831,7 @@ public final class AgvServiceGrpc {
private static final int METHODID_START_MAPPING = 17; private static final int METHODID_START_MAPPING = 17;
private static final int METHODID_STREAM_MAP = 18; private static final int METHODID_STREAM_MAP = 18;
private static final int METHODID_STOP_MAPPING = 19; private static final int METHODID_STOP_MAPPING = 19;
private static final int METHODID_TRANSLATE = 20;
private static final class MethodHandlers<Req, Resp> implements private static final class MethodHandlers<Req, Resp> implements
io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>, io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@ -1849,6 +1930,10 @@ public final class AgvServiceGrpc {
serviceImpl.stopMapping((cmvr.api.Common.CommandHeader.Request) request, serviceImpl.stopMapping((cmvr.api.Common.CommandHeader.Request) request,
(io.grpc.stub.StreamObserver<cmvr.api.Common.CommandHeader.Feedback>) responseObserver); (io.grpc.stub.StreamObserver<cmvr.api.Common.CommandHeader.Feedback>) responseObserver);
break; break;
case METHODID_TRANSLATE:
serviceImpl.translate((cmvr.api.AgvCommand.AgvTranslateCommand.Request) request,
(io.grpc.stub.StreamObserver<cmvr.api.AgvCommand.AgvTranslateCommand.Feedback>) responseObserver);
break;
default: default:
throw new AssertionError(); throw new AssertionError();
} }
@ -1930,6 +2015,7 @@ public final class AgvServiceGrpc {
.addMethod(getStartMappingMethod()) .addMethod(getStartMappingMethod())
.addMethod(getStreamMapMethod()) .addMethod(getStreamMapMethod())
.addMethod(getStopMappingMethod()) .addMethod(getStopMappingMethod())
.addMethod(getTranslateMethod())
.build(); .build();
} }
} }

View File

@ -25,7 +25,7 @@ public final class AgvServiceOuterClass {
java.lang.String[] descriptorData = { java.lang.String[] descriptorData = {
"\n\032cmvr/api/agv_service.proto\022\010cmvr.api\032\025" + "\n\032cmvr/api/agv_service.proto\022\010cmvr.api\032\025" +
"cmvr/api/common.proto\032\032cmvr/api/agv_comm" + "cmvr/api/common.proto\032\032cmvr/api/agv_comm" +
"and.proto2\320\016\n\nAgvService\022f\n\017getRuntimeSt" + "and.proto2\254\017\n\nAgvService\022f\n\017getRuntimeSt" +
"ate\022(.cmvr.api.AgvRuntimeStateCommand.Re" + "ate\022(.cmvr.api.AgvRuntimeStateCommand.Re" +
"quest\032).cmvr.api.AgvRuntimeStateCommand." + "quest\032).cmvr.api.AgvRuntimeStateCommand." +
"Feedback\022r\n\023getNavigationStatus\022,.cmvr.a" + "Feedback\022r\n\023getNavigationStatus\022,.cmvr.a" +
@ -72,7 +72,9 @@ public final class AgvServiceOuterClass {
"\032&.cmvr.api.AgvMapStreamCommand.Feedback" + "\032&.cmvr.api.AgvMapStreamCommand.Feedback" +
"0\001\022P\n\013stopMapping\022\037.cmvr.api.CommandHead" + "0\001\022P\n\013stopMapping\022\037.cmvr.api.CommandHead" +
"er.Request\032 .cmvr.api.CommandHeader.Feed" + "er.Request\032 .cmvr.api.CommandHeader.Feed" +
"backb\006proto3" "back\022Z\n\ttranslate\022%.cmvr.api.AgvTranslat" +
"eCommand.Request\032&.cmvr.api.AgvTranslate" +
"Command.Feedbackb\006proto3"
}; };
descriptor = com.google.protobuf.Descriptors.FileDescriptor descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData, .internalBuildGeneratedFileFrom(descriptorData,

View File

@ -95,6 +95,23 @@ message AgvFollowPathCommand {
} }
} }
// 按指定速度执行固定距离平移命令。
message AgvTranslateCommand {
message Request {
// 通用请求头。header.device_id 指定目标 AGV 设备。
CommandHeader.Request header = 1;
// 固定距离平移参数。
cmvr.msgs.AgvTranslation translation = 2;
}
message Feedback {
// 仅表示控制器是否接受命令,不表示平移已经完成。
CommandHeader.Feedback header = 1;
}
}
// 下发底盘速度命令。 // 下发底盘速度命令。
message AgvSetVelocityCommand { message AgvSetVelocityCommand {
// 请求体。 // 请求体。

View File

@ -69,4 +69,8 @@ service AgvService {
// 停止当前建图/扫图会话。 // 停止当前建图/扫图会话。
rpc stopMapping(CommandHeader.Request) returns (CommandHeader.Feedback); rpc stopMapping(CommandHeader.Request) returns (CommandHeader.Feedback);
// 按指定速度平移固定距离。成功返回仅表示控制器已接受命令。
rpc translate(AgvTranslateCommand.Request) returns (AgvTranslateCommand.Feedback);
} }

View File

@ -14,6 +14,29 @@ message AgvPose2d {
double theta = 3; double theta = 3;
} }
// 固定距离平移使用的距离参考模式。
enum AgvTranslationMode {
// 根据底盘里程计算运动距离。
AGV_TRANSLATION_MODE_ODOMETRY = 0;
// 根据定位结果计算运动距离。
AGV_TRANSLATION_MODE_LOCALIZATION = 1;
}
// AGV 车体坐标系下的固定距离平移参数。
message AgvTranslation {
// 平移距离的绝对值,单位:米,必须大于 0。
double distance = 1;
// 车体 X 方向速度,单位:米/秒;正为向前,负为向后。
double vx = 2;
// 车体 Y 方向速度,单位:米/秒;正为向左,负为向右。
double vy = 3;
// 距离参考模式;默认使用里程模式。
AgvTranslationMode mode = 4;
}
// AGV 车体坐标系下的平面速度。 // AGV 车体坐标系下的平面速度。
message AgvVelocity { message AgvVelocity {
// 车体 X 方向线速度,单位:米/秒。 // 车体 X 方向线速度,单位:米/秒。
@ -24,6 +47,9 @@ message AgvVelocity {
double wz = 3; double wz = 3;
} }
// AGV 电池状态。 // AGV 电池状态。
message AgvBatteryState { message AgvBatteryState {
// 电量比例,范围:[0, 1],例如 0.8 表示 80%。 // 电量比例,范围:[0, 1],例如 0.8 表示 80%。