Skip to content

Commit 74a7a6f

Browse files
committed
Add KeepIn and KeepOut geofence boxes
## Why is this being changed? This is being changed because of Northrop's requirement of having a KeepIn and KeepOut box for all vehicles. The KeepIn area is an area that all vehicles must stay inside of, and will be about the size of the mission field/runway. The KeepOut area is an area that all vehicles must stay outside of, and will be the location of all student/Northrop observers. ## What was changed to address this problem? In order to address the problem, two geofence buttons were created inside of the missionWindow UI tah tallows the GCS operator to dynamically create the two boxes individually, separating them by color. ## How was this change tested? This change was tested with npm test.
1 parent e82c5e0 commit 74a7a6f

File tree

8 files changed

+177
-91
lines changed

8 files changed

+177
-91
lines changed

.env.example

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/common/struct/Vehicle.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,6 @@ export default class Vehicle {
260260
this.sendMessage({
261261
type: 'start',
262262
jobType,
263-
geofence: {
264-
topLeft: [0, 0],
265-
botRight: [0, 0],
266-
keepOut: true,
267-
},
268263
});
269264

270265
this.updateEventHandler.addHandler<VehicleStatus>('status', (value): boolean => {

src/renderer/mainWindow/map/MapContainer.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export default class MapContainer extends Component<ThemeProps, State> {
101101
*/
102102
private ref: React.RefObject<Map>;
103103

104+
104105
public constructor(props: ThemeProps) {
105106
super(props);
106107

@@ -318,7 +319,7 @@ export default class MapContainer extends Component<ThemeProps, State> {
318319
boundingBoxes.forEach((boundingBox): void => {
319320
if (!newBoundingBoxes[boundingBox.name]) {
320321
newBoundingBoxes[boundingBox.name] = {
321-
color: boundingBox.color || 'red',
322+
color: boundingBox.color || 'blue',
322323
bounds: boundingBox.bounds || (viewport.center && {
323324
top: viewport.center[0],
324325
bottom: viewport.center[0],

src/renderer/missionWindow/MissionWindow.tsx

Lines changed: 115 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,17 @@ const title: { [missionName in MissionInformation.MissionName]: string } = {
5454
uuvRescue: 'UUV Rescue',
5555
};
5656

57-
type GeofenceChecklistType = 'geofenceTop' | 'geofenceLeft' | 'geofenceRight' | 'geofenceBottom';
57+
type GeofenceChecklistType = 'geofenceKeepInTop' | 'geofenceKeepInLeft' | 'geofenceKeepInRight' | 'geofenceKeepInBottom' | 'geofenceKeepOutTop' | 'geofenceKeepOutLeft' | 'geofenceKeepOutRight' | 'geofenceKeepOutBottom';
5858

5959
const checklistCache: { [check in GeofenceChecklistType ]: number | undefined} = {
60-
geofenceTop: undefined,
61-
geofenceLeft: undefined,
62-
geofenceRight: undefined,
63-
geofenceBottom: undefined,
60+
geofenceKeepInTop: undefined,
61+
geofenceKeepInLeft: undefined,
62+
geofenceKeepInRight: undefined,
63+
geofenceKeepInBottom: undefined,
64+
geofenceKeepOutTop: undefined,
65+
geofenceKeepOutLeft: undefined,
66+
geofenceKeepOutRight: undefined,
67+
geofenceKeepOutBottom: undefined,
6468
};
6569

6670
type Locked = {
@@ -223,50 +227,98 @@ export default class MissionWindow extends Component<ThemeProps, State> {
223227
const name = event.target.name as GeofenceChecklistType;
224228
const value = parseInt(event.target.value, 10) || 0;
225229
switch (name) {
226-
case 'geofenceTop':
230+
case 'geofenceKeepInTop':
227231
ipc.postUpdateBoundingBoxes(true, {
228-
name: 'Geofencing',
232+
name: 'geofenceContainerKeepIn',
229233
bounds: {
230234
top: value,
231-
bottom: checklist.geofenceBottom as number,
232-
left: checklist.geofenceLeft as number,
233-
right: checklist.geofenceRight as number,
235+
bottom: checklist.geofenceKeepInBottom as number,
236+
left: checklist.geofenceKeepInLeft as number,
237+
right: checklist.geofenceKeepInRight as number,
234238
},
235239
});
236240
break;
237241

238-
case 'geofenceLeft':
242+
case 'geofenceKeepInLeft':
239243
ipc.postUpdateBoundingBoxes(true, {
240-
name: 'Geofencing',
244+
name: 'geofenceContainerKeepIn',
241245
bounds: {
242-
top: checklist.geofenceTop as number,
243-
bottom: checklist.geofenceBottom as number,
246+
top: checklist.geofenceKeepInTop as number,
247+
bottom: checklist.geofenceKeepInBottom as number,
244248
left: value,
245-
right: checklist.geofenceRight as number,
249+
right: checklist.geofenceKeepInRight as number,
246250
},
247251
});
248252
break;
249253

250-
case 'geofenceRight':
254+
case 'geofenceKeepInRight':
251255
ipc.postUpdateBoundingBoxes(true, {
252-
name: 'Geofencing',
256+
name: 'geofenceContainerKeepIn',
253257
bounds: {
254-
top: checklist.geofenceTop as number,
255-
bottom: checklist.geofenceBottom as number,
256-
left: checklist.geofenceLeft as number,
258+
top: checklist.geofenceKeepInTop as number,
259+
bottom: checklist.geofenceKeepInBottom as number,
260+
left: checklist.geofenceKeepInLeft as number,
257261
right: value,
258262
},
259263
});
260264
break;
261265

262-
case 'geofenceBottom':
266+
case 'geofenceKeepInBottom':
263267
ipc.postUpdateBoundingBoxes(true, {
264-
name: 'Geofencing',
268+
name: 'geofenceContainerKeepIn',
265269
bounds: {
266-
top: checklist.geofenceTop as number,
270+
top: checklist.geofenceKeepInTop as number,
267271
bottom: value,
268-
left: checklist.geofenceLeft as number,
269-
right: checklist.geofenceRight as number,
272+
left: checklist.geofenceKeepInLeft as number,
273+
right: checklist.geofenceKeepInRight as number,
274+
},
275+
});
276+
break;
277+
278+
case 'geofenceKeepOutTop':
279+
ipc.postUpdateBoundingBoxes(true, {
280+
name: 'geofenceContainerKeepOut',
281+
bounds: {
282+
top: value,
283+
bottom: checklist.geofenceKeepOutBottom as number,
284+
left: checklist.geofenceKeepOutLeft as number,
285+
right: checklist.geofenceKeepOutRight as number,
286+
},
287+
});
288+
break;
289+
290+
case 'geofenceKeepOutLeft':
291+
ipc.postUpdateBoundingBoxes(true, {
292+
name: 'geofenceContainerKeepOut',
293+
bounds: {
294+
top: checklist.geofenceKeepOutTop as number,
295+
bottom: checklist.geofenceKeepOutBottom as number,
296+
left: value,
297+
right: checklist.geofenceKeepOutRight as number,
298+
},
299+
});
300+
break;
301+
302+
case 'geofenceKeepOutRight':
303+
ipc.postUpdateBoundingBoxes(true, {
304+
name: 'geofenceContainerKeepOut',
305+
bounds: {
306+
top: checklist.geofenceKeepOutTop as number,
307+
bottom: checklist.geofenceKeepOutBottom as number,
308+
left: checklist.geofenceKeepOutLeft as number,
309+
right: value,
310+
},
311+
});
312+
break;
313+
314+
case 'geofenceKeepOutBottom':
315+
ipc.postUpdateBoundingBoxes(true, {
316+
name: 'geofenceContainerKeepOut',
317+
bounds: {
318+
top: checklist.geofenceKeepOutTop as number,
319+
bottom: value,
320+
left: checklist.geofenceKeepOutLeft as number,
321+
right: checklist.geofenceKeepOutRight as number,
270322
},
271323
});
272324
break;
@@ -368,11 +420,18 @@ export default class MissionWindow extends Component<ThemeProps, State> {
368420

369421
boundingBoxes.forEach((boxpoint): void => {
370422
switch (boxpoint.name) {
371-
case 'Geofencing':
372-
checks.geofenceTop = boxpoint.bounds.top;
373-
checks.geofenceRight = boxpoint.bounds.right;
374-
checks.geofenceLeft = boxpoint.bounds.left;
375-
checks.geofenceBottom = boxpoint.bounds.bottom;
423+
case 'geofenceContainerKeepIn':
424+
checks.geofenceKeepInTop = boxpoint.bounds.top;
425+
checks.geofenceKeepInRight = boxpoint.bounds.right;
426+
checks.geofenceKeepInLeft = boxpoint.bounds.left;
427+
checks.geofenceKeepInBottom = boxpoint.bounds.bottom;
428+
break;
429+
430+
case 'geofenceContainerKeepOut':
431+
checks.geofenceKeepOutTop = boxpoint.bounds.top;
432+
checks.geofenceKeepOutRight = boxpoint.bounds.right;
433+
checks.geofenceKeepOutLeft = boxpoint.bounds.left;
434+
checks.geofenceKeepOutBottom = boxpoint.bounds.bottom;
376435
break;
377436

378437
default: break;
@@ -447,7 +506,10 @@ export default class MissionWindow extends Component<ThemeProps, State> {
447506
private unlockParameterInputs(waypointType: string): void {
448507
const { locked: newLocked } = this.state;
449508

450-
if (waypointType === 'geofence') {
509+
if (waypointType === 'geofenceContainerKeepIn') {
510+
newLocked.geofence = false;
511+
}
512+
if (waypointType === 'geofenceContainerKeepOut') {
451513
newLocked.geofence = false;
452514
}
453515

@@ -486,10 +548,10 @@ export default class MissionWindow extends Component<ThemeProps, State> {
486548
*/
487549

488550
const unlockStartMissionButton = information[missionName].parameters !== undefined
489-
&& checklist.geofenceTop !== undefined
490-
&& checklist.geofenceBottom !== undefined
491-
&& checklist.geofenceLeft !== undefined
492-
&& checklist.geofenceRight !== undefined;
551+
&& checklist.geofenceKeepInTop !== undefined
552+
&& checklist.geofenceKeepInBottom !== undefined
553+
&& checklist.geofenceKeepInLeft !== undefined
554+
&& checklist.geofenceKeepInRight !== undefined;
493555

494556
return (
495557
<div className={`missionWrapper${theme === 'dark' ? '_dark' : ''}`}>
@@ -516,16 +578,27 @@ export default class MissionWindow extends Component<ThemeProps, State> {
516578
<h1 style={{ marginTop: 0 }}>Options</h1>
517579
<MissionOptions title={title} missionNames={missionNames} options={options} />
518580
</div>
519-
<div className="geofenceContainer">
520-
<h1>Geofencing</h1>
521-
<input className="inputFields" type="number" name="geofenceScanTop" value={checklist.geofenceTop || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Top" />
581+
<div className="geofenceContainerKeepIn">
582+
<h1>Geofencing KeepIn</h1>
583+
<input className="inputFields" type="number" name="geofenceScanTop" value={checklist.geofenceKeepInTop || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Top" />
584+
<br />
585+
<input className="inputFields" type="number" name="geofenceBottom" value={checklist.geofenceKeepInBottom || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Bottom" />
586+
<br />
587+
<input className="inputFields" type="number" name="geofenceLeft" value={checklist.geofenceKeepInLeft || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Left" />
588+
<br />
589+
<input className="inputFields" type="number" name="geofenceRight" value={checklist.geofenceKeepInRight || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Right" />
590+
<CreateBoundingBoxButton theme={theme} name="geofenceContainerKeepIn" value="geofenceContainerKeepIn" color="green" />
591+
</div>
592+
<div className="geofenceContainerKeepOut">
593+
<h1>Geofencing KeepOut</h1>
594+
<input className="inputFields" type="number" name="geofenceScanTop" value={checklist.geofenceKeepOutTop || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Top" />
522595
<br />
523-
<input className="inputFields" type="number" name="geofenceBottom" value={checklist.geofenceBottom || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Bottom" />
596+
<input className="inputFields" type="number" name="geofenceBottom" value={checklist.geofenceKeepOutBottom || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Bottom" />
524597
<br />
525-
<input className="inputFields" type="number" name="geofenceLeft" value={checklist.geofenceLeft || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Left" />
598+
<input className="inputFields" type="number" name="geofenceLeft" value={checklist.geofenceKeepOutLeft || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Left" />
526599
<br />
527-
<input className="inputFields" type="number" name="geofenceRight" value={checklist.geofenceRight || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Right" />
528-
<CreateBoundingBoxButton theme={theme} name="geofence" value="Geofencing" />
600+
<input className="inputFields" type="number" name="geofenceRight" value={checklist.geofenceKeepOutRight || ''} disabled={locked.geofence} onChange={this.onChange} placeholder="Right" />
601+
<CreateBoundingBoxButton theme={theme} name="geofenceContainerKeepOut" value="geofenceContainerKeepOut" color="red" />
529602
</div>
530603
<div className="buttonContainer">
531604
{status === 'ready' && <button type="button" disabled={!unlockStartMissionButton} onClick={this.postStartMissions}>Start Missions</button>}

src/renderer/missionWindow/extra/CreateBoundingBoxButton.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export interface CreateBoundingBoxButtonProps extends ThemeProps{
1313
* Name of the box itself, when it shows up on the map.
1414
*/
1515
value: string;
16+
17+
color: string;
1618
}
1719

1820
export default class CreateBoundingBoxButton extends PureComponent<CreateBoundingBoxButtonProps> {
@@ -23,9 +25,9 @@ export default class CreateBoundingBoxButton extends PureComponent<CreateBoundin
2325
}
2426

2527
private onClick(): void {
26-
const { name, value } = this.props;
28+
const { name, value, color } = this.props;
2729
ipc.postUnlockParameterInputs(name);
28-
ipc.postCreateBoundingBoxes({ name: value });
30+
ipc.postCreateBoundingBoxes({ name: value, color });
2931
}
3032

3133
public render(): ReactNode {

src/renderer/missionWindow/mission.css

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
height: 100%;
77
width: 100;
88
grid-template-areas:
9-
'selector selector selector mapping'
10-
'parameter parameter parameter mapping'
11-
'parameter parameter parameter mapping'
12-
'parameter parameter parameter mapping'
13-
'geofence geofence geofence options'
14-
'geofence geofence geofence options'
15-
'button button button options';
16-
grid-template-rows: 25px 1fr 1fr 0.8fr 1fr 0.3fr 25px;
9+
'selector selector selector mapping'
10+
'parameter parameter parameter mapping'
11+
'parameter parameter parameter mapping'
12+
'parameter parameter parameter mapping'
13+
'geofenceKeepIn geofenceKeepIn geofenceKeepOut options'
14+
'geofenceKeepIn geofenceKeepIn geofenceKeepOut options'
15+
'button button button options';
16+
grid-template-rows: 25px 1fr 1fr 1fr 1fr 0.2fr 25px;
1717
grid-template-columns: repeat(4, 1fr);
1818
}
1919

@@ -27,8 +27,13 @@
2727
padding-left: 20px;
2828
}
2929

30-
.geofenceContainer {
31-
grid-area: geofence;
30+
.geofenceContainerKeepIn {
31+
grid-area: geofenceContainerKeepIn;
32+
padding-left: 20px;
33+
}
34+
35+
.geofenceContainerKeepOut {
36+
grid-area: geofenceContainerKeepOut;
3237
padding-left: 20px;
3338
}
3439

src/renderer/missionWindow/parameter/VTOLSearch.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ export class VTOLSearch extends Component<VTOLSearchProps, State> {
233233
<input className="inputFields" type="number" name="quickScanLeft" value={checklist.quickScanLeft || ''} disabled={locked.quickScan} onChange={this.onChange} placeholder="Left" />
234234
<br />
235235
<input className="inputFields" type="number" name="quickScanRight" value={checklist.quickScanRight || ''} disabled={locked.quickScan} onChange={this.onChange} placeholder="Right" />
236-
<CreateBoundingBoxButton theme={theme} name="quickScan" value="Bounding Box" />
236+
<CreateBoundingBoxButton theme={theme} name="quickScan" value="Bounding Box" color="red" />
237237
</div>
238238
);
239239
}

0 commit comments

Comments
 (0)