diff --git a/src/common/struct/Vehicle.ts b/src/common/struct/Vehicle.ts index 1b3e9e2e..dfe355a7 100644 --- a/src/common/struct/Vehicle.ts +++ b/src/common/struct/Vehicle.ts @@ -260,11 +260,6 @@ export default class Vehicle { this.sendMessage({ type: 'start', jobType, - geofence: { - topLeft: [0, 0], - botRight: [0, 0], - keepOut: true, - }, }); this.updateEventHandler.addHandler('status', (value): boolean => { diff --git a/src/renderer/mainWindow/map/MapContainer.tsx b/src/renderer/mainWindow/map/MapContainer.tsx index 0e4e5b8f..38e45cf1 100644 --- a/src/renderer/mainWindow/map/MapContainer.tsx +++ b/src/renderer/mainWindow/map/MapContainer.tsx @@ -318,7 +318,7 @@ export default class MapContainer extends Component { boundingBoxes.forEach((boundingBox): void => { if (!newBoundingBoxes[boundingBox.name]) { newBoundingBoxes[boundingBox.name] = { - color: boundingBox.color || 'red', + color: boundingBox.color || 'black', bounds: boundingBox.bounds || (viewport.center && { top: viewport.center[0], bottom: viewport.center[0], diff --git a/src/renderer/missionWindow/MissionWindow.tsx b/src/renderer/missionWindow/MissionWindow.tsx index c625ce73..98941e59 100644 --- a/src/renderer/missionWindow/MissionWindow.tsx +++ b/src/renderer/missionWindow/MissionWindow.tsx @@ -54,13 +54,17 @@ const title: { [missionName in MissionInformation.MissionName]: string } = { uuvRescue: 'UUV Rescue', }; -type GeofenceChecklistType = 'geofenceTop' | 'geofenceLeft' | 'geofenceRight' | 'geofenceBottom'; +type GeofenceChecklistType = 'geofenceKeepInTop' | 'geofenceKeepInLeft' | 'geofenceKeepInRight' | 'geofenceKeepInBottom' | 'geofenceKeepOutTop' | 'geofenceKeepOutLeft' | 'geofenceKeepOutRight' | 'geofenceKeepOutBottom'; const checklistCache: { [check in GeofenceChecklistType ]: number | undefined} = { - geofenceTop: undefined, - geofenceLeft: undefined, - geofenceRight: undefined, - geofenceBottom: undefined, + geofenceKeepInTop: undefined, + geofenceKeepInLeft: undefined, + geofenceKeepInRight: undefined, + geofenceKeepInBottom: undefined, + geofenceKeepOutTop: undefined, + geofenceKeepOutLeft: undefined, + geofenceKeepOutRight: undefined, + geofenceKeepOutBottom: undefined, }; type Locked = { @@ -223,50 +227,98 @@ export default class MissionWindow extends Component { const name = event.target.name as GeofenceChecklistType; const value = parseInt(event.target.value, 10) || 0; switch (name) { - case 'geofenceTop': + case 'geofenceKeepInTop': ipc.postUpdateBoundingBoxes(true, { - name: 'Geofencing', + name: 'Geofence Keep-In', bounds: { top: value, - bottom: checklist.geofenceBottom as number, - left: checklist.geofenceLeft as number, - right: checklist.geofenceRight as number, + bottom: checklist.geofenceKeepInBottom as number, + left: checklist.geofenceKeepInLeft as number, + right: checklist.geofenceKeepInRight as number, }, }); break; - case 'geofenceLeft': + case 'geofenceKeepInLeft': ipc.postUpdateBoundingBoxes(true, { - name: 'Geofencing', + name: 'Geofence Keep-In', bounds: { - top: checklist.geofenceTop as number, - bottom: checklist.geofenceBottom as number, + top: checklist.geofenceKeepInTop as number, + bottom: checklist.geofenceKeepInBottom as number, left: value, - right: checklist.geofenceRight as number, + right: checklist.geofenceKeepInRight as number, }, }); break; - case 'geofenceRight': + case 'geofenceKeepInRight': ipc.postUpdateBoundingBoxes(true, { - name: 'Geofencing', + name: 'Geofence Keep-In', bounds: { - top: checklist.geofenceTop as number, - bottom: checklist.geofenceBottom as number, - left: checklist.geofenceLeft as number, + top: checklist.geofenceKeepInTop as number, + bottom: checklist.geofenceKeepInBottom as number, + left: checklist.geofenceKeepInLeft as number, right: value, }, }); break; - case 'geofenceBottom': + case 'geofenceKeepInBottom': ipc.postUpdateBoundingBoxes(true, { - name: 'Geofencing', + name: 'Geofence Keep-In', bounds: { - top: checklist.geofenceTop as number, + top: checklist.geofenceKeepInTop as number, bottom: value, - left: checklist.geofenceLeft as number, - right: checklist.geofenceRight as number, + left: checklist.geofenceKeepInLeft as number, + right: checklist.geofenceKeepInRight as number, + }, + }); + break; + + case 'geofenceKeepOutTop': + ipc.postUpdateBoundingBoxes(true, { + name: 'Geofence Keep-Out', + bounds: { + top: value, + bottom: checklist.geofenceKeepOutBottom as number, + left: checklist.geofenceKeepOutLeft as number, + right: checklist.geofenceKeepOutRight as number, + }, + }); + break; + + case 'geofenceKeepOutLeft': + ipc.postUpdateBoundingBoxes(true, { + name: 'Geofence Keep-Out', + bounds: { + top: checklist.geofenceKeepOutTop as number, + bottom: checklist.geofenceKeepOutBottom as number, + left: value, + right: checklist.geofenceKeepOutRight as number, + }, + }); + break; + + case 'geofenceKeepOutRight': + ipc.postUpdateBoundingBoxes(true, { + name: 'Geofence Keep-Out', + bounds: { + top: checklist.geofenceKeepOutTop as number, + bottom: checklist.geofenceKeepOutBottom as number, + left: checklist.geofenceKeepOutLeft as number, + right: value, + }, + }); + break; + + case 'geofenceKeepOutBottom': + ipc.postUpdateBoundingBoxes(true, { + name: 'Geofence Keep-Out', + bounds: { + top: checklist.geofenceKeepOutTop as number, + bottom: value, + left: checklist.geofenceKeepOutLeft as number, + right: checklist.geofenceKeepOutRight as number, }, }); break; @@ -368,11 +420,18 @@ export default class MissionWindow extends Component { boundingBoxes.forEach((boxpoint): void => { switch (boxpoint.name) { - case 'Geofencing': - checks.geofenceTop = boxpoint.bounds.top; - checks.geofenceRight = boxpoint.bounds.right; - checks.geofenceLeft = boxpoint.bounds.left; - checks.geofenceBottom = boxpoint.bounds.bottom; + case 'geofenceContainerKeepIn': + checks.geofenceKeepInTop = boxpoint.bounds.top; + checks.geofenceKeepInRight = boxpoint.bounds.right; + checks.geofenceKeepInLeft = boxpoint.bounds.left; + checks.geofenceKeepInBottom = boxpoint.bounds.bottom; + break; + + case 'geofenceContainerKeepOut': + checks.geofenceKeepOutTop = boxpoint.bounds.top; + checks.geofenceKeepOutRight = boxpoint.bounds.right; + checks.geofenceKeepOutLeft = boxpoint.bounds.left; + checks.geofenceKeepOutBottom = boxpoint.bounds.bottom; break; default: break; @@ -447,7 +506,10 @@ export default class MissionWindow extends Component { private unlockParameterInputs(waypointType: string): void { const { locked: newLocked } = this.state; - if (waypointType === 'geofence') { + if (waypointType === 'geofenceContainerKeepIn') { + newLocked.geofence = false; + } + if (waypointType === 'geofenceContainerKeepOut') { newLocked.geofence = false; } @@ -485,11 +547,15 @@ export default class MissionWindow extends Component { * (and no mission is running). */ - const unlockStartMissionButton = information[missionName].parameters !== undefined - && checklist.geofenceTop !== undefined - && checklist.geofenceBottom !== undefined - && checklist.geofenceLeft !== undefined - && checklist.geofenceRight !== undefined; + const unlockStartMissionButton : boolean = information[missionName].parameters !== undefined + && checklist.geofenceKeepInTop !== undefined + && checklist.geofenceKeepInBottom !== undefined + && checklist.geofenceKeepInLeft !== undefined + && checklist.geofenceKeepInRight !== undefined + && checklist.geofenceKeepOutTop !== undefined + && checklist.geofenceKeepOutBottom !== undefined + && checklist.geofenceKeepOutLeft !== undefined + && checklist.geofenceKeepOutRight !== undefined; return (
@@ -516,16 +582,27 @@ export default class MissionWindow extends Component {

Options

-
-

Geofencing

- +
+

Geofencing KeepIn

+ +
+ +
+ +
+ + +
+
+

Geofencing KeepOut

+
- +
- +
- - + +
{status === 'ready' && } diff --git a/src/renderer/missionWindow/extra/CreateBoundingBoxButton.tsx b/src/renderer/missionWindow/extra/CreateBoundingBoxButton.tsx index b0d76365..ee0e0582 100644 --- a/src/renderer/missionWindow/extra/CreateBoundingBoxButton.tsx +++ b/src/renderer/missionWindow/extra/CreateBoundingBoxButton.tsx @@ -13,6 +13,11 @@ export interface CreateBoundingBoxButtonProps extends ThemeProps{ * Name of the box itself, when it shows up on the map. */ value: string; + + /** + *Color of the box as it appears on the map. + */ + color: string; } export default class CreateBoundingBoxButton extends PureComponent { @@ -23,9 +28,9 @@ export default class CreateBoundingBoxButton extends PureComponent {
- +
); } diff --git a/src/types/message.ts b/src/types/message.ts index 1e518a76..ba80238d 100644 --- a/src/types/message.ts +++ b/src/types/message.ts @@ -18,9 +18,7 @@ interface MessageBase { */ type: string; } - -// Definitions for all messages from GCS to vehicles. - +// Definitions for all messages from GCS to vehicles export interface StartMessage extends MessageBase { type: 'start'; @@ -28,28 +26,6 @@ export interface StartMessage extends MessageBase { * Name of job to perform. */ jobType: JobType; - - /** - * Geofencing coordinates in the form of a rectangle, and geofence type sent with start message. - */ - geofence: { - - /** - * Top Left coordinate of geofencing rectangle, in form of latitude, longitude. - */ - topLeft: [number, number]; - - /** - * Bottom right coordinate of geofencing rectangle, in form of latitude, longitude. - */ - botRight: [number, number]; - - /** - * Boolean to specify whether geofence is keep out type (true), or keep in type (false). - */ - keepOut: boolean; - }; - } /** @@ -103,6 +79,28 @@ export interface StopMessage extends MessageBase { type: 'stop'; } +export interface GeofenceMessage extends MessageBase { + type: 'geofence'; + + /** + * Geofencing coordinates in the form of a rectangle. + */ + geofence: { + 'keepOut': [number, number][], + 'keepIn': [number, number][] + } +} + +/** + * Type guard for Geofence Message. + */ +function isGeofenceMessage(message: Message): boolean { + return message.type === 'geofence' + && message.geofence !== undefined + && Array.isArray(message.geofence.keepIn) + && Array.isArray(message.geofence.keepIn); +} + /** * Type guard for Stop Message. */ @@ -280,9 +278,10 @@ export function isBadMessage(message: Message): boolean { /** * All types of messages sent to and from the GCS. */ -export type Message = StartMessage | AddMissionMessage | PauseMessage | ResumeMessage | StopMessage -| ConnectionAckMessage | UpdateMessage | POIMessage | CompleteMessage | ConnectMessage -| AcknowledgementMessage | BadMessage; + +export type Message = | StartMessage | AddMissionMessage | PauseMessage | ResumeMessage | +StopMessage | GeofenceMessage | ConnectionAckMessage | UpdateMessage | POIMessage | CompleteMessage +| ConnectMessage | AcknowledgementMessage | BadMessage; /** * Simply checks if the message has a valid type field. This is different from the type @@ -298,6 +297,7 @@ export function isMessage(message: { [key: string]: any }): boolean { 'pause', 'resume', 'stop', + 'geofence', 'connectionAck', 'update', 'poi', @@ -348,6 +348,7 @@ export const TypeGuard = { isPauseMessage, isResumeMessage, isStopMessage, + isGeofenceMessage, isConnectionAcknowledgementMessage, isUpdateMessage, isPOIMessage,