功能概述
指令飞行功能暂时只支持机场,飞行器可以从空闲(idle)状态响应或暂停正在执行的航线任务。通过手动方式(manual)控制设备和负载。
一键起飞(空闲状态)
调用一键起飞接口 POST:/{sn}/jobs/takeoff-to-point
@PostMapping("/{sn}/jobs/takeoff-to-point")
public HttpResultResponse takeoffToPoint(@PathVariable String sn, @Valid @RequestBody TakeoffToPointParam param) {
return controlService.takeoffToPoint(sn, param);
}
// service
@Override
public HttpResultResponse takeoffToPoint(String sn, TakeoffToPointParam param) {
// 检查一键起飞条件 当前状态是否空闲 获取飞行控制权
checkTakeoffCondition(sn);
param.setFlightId(UUID.randomUUID().toString());
// 推送一键起飞消息
TopicServicesResponse<ServicesReplyData> response = abstractControlService.takeoffToPoint(
SDKManager.getDeviceSDK(sn), mapper.convertValue(param, TakeoffToPointRequest.class));
ServicesReplyData reply = response.getData();
return reply.getResult().isSuccess() ?
HttpResultResponse.success()
: HttpResultResponse.error("The drone failed to take off. " + reply.getResult());
}
// 发送消息
@CloudSDKVersion(exclude = GatewayTypeEnum.RC)
public TopicServicesResponse<ServicesReplyData> takeoffToPoint(GatewayManager gateway, TakeoffToPointRequest request) {
return servicesPublish.publish(
gateway.getGatewaySn(),
ControlMethodEnum.TAKEOFF_TO_POINT.getMethod(),
request);
}
通过mqtt对一键起飞任务进度通知
Topic: thing/product/{gateway_sn}/events
Direction: up
Method: takeoff_to_point_progress
// 进入对应ChannelName.INBOUND_EVENTS_TAKEOFF_TO_POINT_PROGRESS
@ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_TAKEOFF_TO_POINT_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS)
public TopicEventsResponse<MqttReply> takeoffToPointProgress(TopicEventsRequest<TakeoffToPointProgress> request, MessageHeaders headers) {
throw new UnsupportedOperationException("takeoffToPointProgress not implemented");
}
// service
@Override
public TopicEventsResponse<MqttReply> takeoffToPointProgress(TopicEventsRequest<TakeoffToPointProgress> request, MessageHeaders headers) {
// 网关sn
String dockSn = request.getGateway();
// 获取网关设备
Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(dockSn);
if (deviceOpt.isEmpty()) {
log.error("The dock is offline.");
return null;
}
TakeoffToPointProgress eventsReceiver = request.getData();
// 发送ws 消息通知web
webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(),
BizCodeEnum.TAKE_OFF_TO_POINT_PROGRESS.getCode(),
ResultNotifyDTO.builder().sn(dockSn)
.message(eventsReceiver.getResult().toString())
.result(eventsReceiver.getResult().getCode())
.build());
return new TopicEventsResponse<MqttReply>().setData(MqttReply.success());
}
flyto(暂停正在执行的航线任务)
- flyto 需要先获取进入drc指令飞行控制模式,先通过接口进入drc模式 POST:/workspaces/{workspace_id}/drc/enter
@PostMapping("/workspaces/{workspace_id}/drc/enter")
public HttpResultResponse drcEnter(@PathVariable("workspace_id") String workspaceId, @Valid @RequestBody DrcModeParam param) {
JwtAclDTO acl = drcService.deviceDrcEnter(workspaceId, param);
return HttpResultResponse.success(acl);
}
// service
@Override
public JwtAclDTO deviceDrcEnter(String workspaceId, DrcModeParam param) {
// drc 消息相关主题
String topic = TopicConst.THING_MODEL_PRE + TopicConst.PRODUCT + param.getDockSn() + TopicConst.DRC;
String pubTopic = topic + TopicConst.DOWN;
String subTopic = topic + TopicConst.UP;
// 如果现在是drc模式 直接刷新权限
if (deviceService.checkDockDrcMode(param.getDockSn())
&& param.getClientId().equals(this.getDrcModeInRedis(param.getDockSn()))) {
refreshAcl(param.getDockSn(), param.getClientId(), topic, subTopic);
return JwtAclDTO.builder().sub(List.of(subTopic)).pub(List.of(pubTopic)).build();
}
// 检查是否满足进入drc模式的条件 航线任务是否暂停,无人机是否在空中 获取飞行器控制权限
checkDrcModeCondition(workspaceId, param.getDockSn());
// 发送进入drc模式的请求 构建相关drc消息通道
TopicServicesResponse<ServicesReplyData> reply = abstractControlService.drcModeEnter(
SDKManager.getDeviceSDK(param.getDockSn()),
new DrcModeEnterRequest()
.setMqttBroker(MqttPropertyConfiguration.getMqttBrokerWithDrc(param.getDockSn() + "-" + System.currentTimeMillis(), param.getDockSn(),
RedisConst.DRC_MODE_ALIVE_SECOND.longValue(),
Map.of(MapKeyConst.ACL, objectMapper.convertValue(JwtAclDTO.builder()
.pub(List.of(subTopic))
.sub(List.of(pubTopic))
.build(), new TypeReference<Map<String, ?>>() {}))))
.setHsiFrequency(1).setOsdFrequency(10));
if (!reply.getData().getResult().isSuccess()) {
throw new RuntimeException("进入命令飞行控制模式失败,请稍后再试!错误码:"+reply.getData().getResult().getCode());
}
refreshAcl(param.getDockSn(), param.getClientId(), pubTopic, subTopic);
return JwtAclDTO.builder().sub(List.of(subTopic)).pub(List.of(pubTopic)).build();
}
- 调用flyto 方法 POST:/{sn}/jobs/fly-to-point
@PostMapping("/{sn}/jobs/fly-to-point")
public HttpResultResponse flyToPoint(@PathVariable String sn, @Valid @RequestBody FlyToPointParam param) {
return controlService.flyToPoint(sn, param);
}
// service
@Override
public HttpResultResponse flyToPoint(String sn, FlyToPointParam param) {
// 检查权限 获取飞行控制
checkFlyToCondition(sn);
param.setFlyToId(UUID.randomUUID().toString());
// 发送mqtt消息
TopicServicesResponse<ServicesReplyData> response = abstractControlService.flyToPoint(
SDKManager.getDeviceSDK(sn), mapper.convertValue(param, FlyToPointRequest.class));
ServicesReplyData reply = response.getData();
return reply.getResult().isSuccess() ?
HttpResultResponse.success()
: HttpResultResponse.error("Flying to the target point failed. " + reply.getResult());
}
flyto进度通知
Topic: thing/product/{gateway_sn}/events
Direction: up
Method: fly_to_point_progress
// ChannelName.INBOUND_EVENTS_FLY_TO_POINT_PROGRESS
@ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLY_TO_POINT_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS)
public TopicEventsResponse<MqttReply> flyToPointProgress(TopicEventsRequest<FlyToPointProgress> request, MessageHeaders headers) {
throw new UnsupportedOperationException("flyToPointProgress not implemented");
}
// service
@Override
public TopicEventsResponse<MqttReply> flyToPointProgress(TopicEventsRequest<FlyToPointProgress> request, MessageHeaders headers) {
String dockSn = request.getGateway();
Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(dockSn);
if (deviceOpt.isEmpty()) {
log.error("The dock is offline.");
return null;
}
FlyToPointProgress eventsReceiver = request.getData();
webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(),
BizCodeEnum.FLY_TO_POINT_PROGRESS.getCode(),
ResultNotifyDTO.builder().sn(dockSn)
.message(eventsReceiver.getResult().toString())
.result(eventsReceiver.getResult().getCode())
.build());
return new TopicEventsResponse<MqttReply>().setData(MqttReply.success());
}