Skip to content

Commit f33e755

Browse files
authored
refactor to create scene bounding box taking into account of nav graphs too (#1072)
* refactor to create scene bounding box taking into account of nav graphs too Signed-off-by: Aaron Chong <[email protected]> * Push alert when a scene bounding box is invalid Signed-off-by: Aaron Chong <[email protected]> * fallback to a generic scale, and changing to better worded warning Signed-off-by: Aaron Chong <[email protected]> --------- Signed-off-by: Aaron Chong <[email protected]>
1 parent 88916c7 commit f33e755

File tree

3 files changed

+56
-17
lines changed

3 files changed

+56
-17
lines changed

packages/rmf-dashboard-framework/src/components/map/map.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Box, styled, Typography } from '@mui/material';
22
import { Line } from '@react-three/drei';
33
import { Canvas, useLoader } from '@react-three/fiber';
4-
import { BuildingMap, FleetState, Level, Lift } from 'api-client';
4+
import { AlertRequest, BuildingMap, FleetState, Level, Lift } from 'api-client';
55
import Debug from 'debug';
66
import React, { ChangeEvent, Suspense } from 'react';
77
import { ErrorBoundary } from 'react-error-boundary';
@@ -518,10 +518,25 @@ export const Map = styled((props: MapProps) => {
518518
</Box>
519519
<Canvas
520520
onCreated={({ camera }) => {
521-
if (!sceneBoundingBox) {
522-
return;
521+
let sceneBoundingBoxToUse = sceneBoundingBox;
522+
if (!sceneBoundingBoxToUse) {
523+
let alertRequest: AlertRequest = {
524+
id: `scene-bounding-${new Date().toLocaleTimeString()}`,
525+
unix_millis_alert_time: new Date().getTime(),
526+
title: 'Map rendering error',
527+
subtitle: 'Missing walls or navigation graphs in Building Map',
528+
message:
529+
'Please verify that the Building Map contains valid walls and navigation graphs, for the map to be displayed properly. Falling back to a generic scale.',
530+
display: true,
531+
tier: 'warning',
532+
responses_available: [],
533+
alert_parameters: [],
534+
task_id: null,
535+
};
536+
AppEvents.pushAlert.next(alertRequest);
537+
sceneBoundingBoxToUse = new Box3(new Vector3(-10, -10, 0), new Vector3(10, 10, 10));
523538
}
524-
const center = sceneBoundingBox.getCenter(new Vector3());
539+
const center = sceneBoundingBoxToUse.getCenter(new Vector3());
525540
camera.position.set(center.x, center.y, center.z + distance);
526541
camera.zoom = zoom;
527542
camera.updateProjectionMatrix();

packages/rmf-dashboard-framework/src/components/map/utils.ts

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export function getDoorCenter(door: Door): [x: number, y: number] {
4141
}
4242
}
4343

44-
interface WallSegment {
44+
interface GraphSegment {
4545
position: number[];
4646
width: number;
4747
height: number;
@@ -52,8 +52,8 @@ interface WallSegment {
5252
const distance = (v1: GraphNode, v2: GraphNode) => Math.hypot(v2.x - v1.x, v2.y - v1.y);
5353
const midPoint = (v1: GraphNode, v2: GraphNode) => [(v2.x + v1.x) / 2, (v2.y + v1.y) / 2];
5454

55-
export const graphToWalls = (graph: Graph): WallSegment[] => {
56-
const walls = [] as WallSegment[];
55+
export const graphToSegments = (graph: Graph): GraphSegment[] => {
56+
const segments = [] as GraphSegment[];
5757
const { edges, vertices } = graph;
5858

5959
edges.map((edge) => {
@@ -69,7 +69,7 @@ export const graphToWalls = (graph: Graph): WallSegment[] => {
6969
const angle = Math.atan2(v1.y - v2.y, v1.x - v2.x) - Math.PI / 2;
7070
const rot = new Euler(0, 0, angle);
7171

72-
return walls.push({
72+
return segments.push({
7373
position,
7474
width,
7575
height,
@@ -78,11 +78,12 @@ export const graphToWalls = (graph: Graph): WallSegment[] => {
7878
});
7979
});
8080

81-
return walls;
81+
return segments;
8282
};
8383

8484
export const findSceneBoundingBoxFromThreeFiber = (level: Level | undefined): Box3 | undefined => {
8585
if (!level) {
86+
console.error('Level is invalid');
8687
return;
8788
}
8889
let minX = Infinity;
@@ -91,20 +92,43 @@ export const findSceneBoundingBoxFromThreeFiber = (level: Level | undefined): Bo
9192
let maxX = -Infinity;
9293
let maxY = -Infinity;
9394
let maxZ = -Infinity;
95+
let valid = false;
9496

95-
const walls = graphToWalls(level.wall_graph);
96-
walls.forEach((wall) => {
97-
const [x, y, z] = wall.position;
98-
const width = wall.width;
99-
const height = wall.height;
97+
const wallSegments = graphToSegments(level.wall_graph);
98+
wallSegments.forEach((segment) => {
99+
const [x, y, z] = segment.position;
100+
const width = segment.width;
101+
const height = segment.height;
100102

101103
minX = Math.min(minX, x - width / 2);
102104
minY = Math.min(minY, y - width / 2);
103105
minZ = Math.min(minZ, z - height / 2);
104106
maxX = Math.max(maxX, x + width / 2);
105107
maxY = Math.max(maxY, y + width / 2);
106108
maxZ = Math.max(maxZ, z + height / 2);
109+
valid = true;
107110
});
108111

112+
level.nav_graphs.forEach((navGraph) => {
113+
const navGraphSegments = graphToSegments(navGraph);
114+
navGraphSegments.forEach((segment) => {
115+
const [x, y, z] = segment.position;
116+
const width = segment.width;
117+
const height = segment.height;
118+
119+
minX = Math.min(minX, x - width / 2);
120+
minY = Math.min(minY, y - width / 2);
121+
minZ = Math.min(minZ, z - height / 2);
122+
maxX = Math.max(maxX, x + width / 2);
123+
maxY = Math.max(maxY, y + width / 2);
124+
maxZ = Math.max(maxZ, z + height / 2);
125+
valid = true;
126+
});
127+
});
128+
129+
if (!valid) {
130+
console.error('Level has invalid wall graphs and nav graphs');
131+
return;
132+
}
109133
return new Box3(new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ));
110134
};

packages/rmf-dashboard-framework/src/components/map/wall-maker.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import { Graph } from 'api-client';
22

33
import { CubeMaker } from './cube-maker';
4-
import { graphToWalls } from './utils';
4+
import { graphToSegments } from './utils';
55

66
interface WallProps {
77
wallGraph: Graph;
88
}
99

1010
export const WallMaker = ({ wallGraph }: WallProps): JSX.Element => {
11-
const walls = graphToWalls(wallGraph);
11+
const wallSegments = graphToSegments(wallGraph);
1212

1313
return (
1414
<>
15-
{walls.map((wall, i) => {
15+
{wallSegments.map((wall, i) => {
1616
return (
1717
<CubeMaker
1818
key={i}

0 commit comments

Comments
 (0)