From 2761085f5fca6e59c19281c83a66b3183b566764 Mon Sep 17 00:00:00 2001 From: Ishan Ajwani Date: Sat, 18 Nov 2023 10:54:33 -0500 Subject: [PATCH] Fixes issue #69 (adds path and next waypoint tracking on map) --- client/src/components/FlightMap.js | 74 +++++++++++++++++++--------- client/src/pages/FlightData/index.js | 64 ++++++++++++++++-------- 2 files changed, 94 insertions(+), 44 deletions(-) diff --git a/client/src/components/FlightMap.js b/client/src/components/FlightMap.js index 01bb2f30..b64b397e 100644 --- a/client/src/components/FlightMap.js +++ b/client/src/components/FlightMap.js @@ -61,9 +61,7 @@ const FlightPlanMap = props => { let mapRef = createRef() const [icons, setIcons] = useState({}) const tileRef = useRef(null) - useEffect(() => { - httpget("/uav/commands/export", response => { let points = response.data.waypoints.map((marker) => { return { num: marker.num, cmd: marker.cmd, p1: marker.p1, p2: marker.p2, p3: marker.p3 * 3.281, p4: marker.p4, lat: marker.lat, lng: marker.lon, alt: marker.alt * 3.281 } // convert altitude from meters to feet @@ -71,7 +69,6 @@ const FlightPlanMap = props => { props.setters.path(points) props.setters.pathSave(structuredClone(points)) }) - var MarkerIcon = L.Icon.extend({ options: { iconSize: [25, 41], @@ -86,7 +83,7 @@ const FlightPlanMap = props => { var NoIcon = L.Icon.extend({ options: { iconSize: [20, 20], - iconAnchor: [10, 10], + iconAnchor: [10, 10], iconUrl: "../assets/icon-transparent.svg", popupAnchor: [0, 0], tooltipAnchor: [0, 0], @@ -119,6 +116,7 @@ const FlightPlanMap = props => { uav: new VehicleIcon({ iconUrl: "../assets/uav.svg" }), uavDirection: new DirectionPointerIcon({ iconUrl: "../assets/pointer.svg" }), uavDirectionOutline: new DirectionPointerIcon({ iconUrl: "../assets/pointer-outline.svg" }), + uavPath: new NoIcon(), water: new VehicleIcon({ iconUrl: "../assets/water-drop.svg" }), }) @@ -126,6 +124,8 @@ const FlightPlanMap = props => { tileRef.current.setUrl("/map/{z}/{x}/{y}.png") }) + + checkInternet() }, []) @@ -143,12 +143,12 @@ const FlightPlanMap = props => { }).catch(() => { try { tileRef.current.setUrl("/map/{z}/{x}/{y}.png") - } catch {} + } catch { } }) } else { try { tileRef.current.setUrl("/map/{z}/{x}/{y}.png") - } catch {} + } catch { } } } useInterval(5000, checkInternet) @@ -179,8 +179,11 @@ const FlightPlanMap = props => { props.setters.pathSaved(false) } + const handleClick = event => { - console.log(props.getters.path) + let waypointNum = props.getters.Awaypoint[0].num + console.log(waypointNum) + console.log(props.getters.path[2]) if (["disabled", "distance"].includes(props.getters.placementMode) || ["jump"].includes(props.getters.placementType)) { return @@ -208,9 +211,9 @@ const FlightPlanMap = props => { second = get[(i + 1) % get.length] } - let m = (second.lat - first.lat)/(second.lng - first.lng) - let x0 = (event.latlng.lng/m + event.latlng.lat - second.lat + m*second.lng)/(m + 1/m) // projection of event point on line - let y0 = -(x0 - event.latlng.lng)/m + event.latlng.lat + let m = (second.lat - first.lat) / (second.lng - first.lng) + let x0 = (event.latlng.lng / m + event.latlng.lat - second.lat + m * second.lng) / (m + 1 / m) // projection of event point on line + let y0 = -(x0 - event.latlng.lng) / m + event.latlng.lat if (m === -Infinity || m === Infinity) { let d = Math.abs(event.latlng.lng - first.lng) @@ -221,7 +224,7 @@ const FlightPlanMap = props => { let lng = event.latlng.lng return [d, (lng > first.lng && lng < second.lng) || (lng > second.lng && lng < first.lng)] } else { - let d = Math.sqrt((x0 - event.latlng.lng)**2 + (y0 - event.latlng.lat)**2) + let d = Math.sqrt((x0 - event.latlng.lng) ** 2 + (y0 - event.latlng.lat) ** 2) if (x0 > Math.min(first.lng, second.lng) && x0 < Math.max(first.lng, second.lng) && y0 > Math.min(first.lat, second.lat) && y0 < Math.max(first.lat, second.lat)) { return [d, true] } else { @@ -321,7 +324,7 @@ const FlightPlanMap = props => { {popupMenu} - : null} + : null} ) } @@ -340,6 +343,15 @@ const FlightPlanMap = props => { return null; }; + const getTargetWaypoint = () => { + + if (props.getters.Awaypoint.length > 0 && props.getters.planePoints.length > 0 && props.getters.path) { + let waypointNum = props.getters.Awaypoint[0].num + return [props.getters.planePoints[props.getters.planePoints.length - 1], props.getters.path[waypointNum]] + } + return [] + } + const MarkerPopup = ({ marker, i, datatype }) => { return (
@@ -398,7 +410,7 @@ const FlightPlanMap = props => { Jump From positiveSignedIntValidation(v, marker.p0, (k) => { let path = props.getters.path - props.setters.path([...path.slice(0, i), {...marker, p0: k}, ...path.slice(i + 1)]) + props.setters.path([...path.slice(0, i), { ...marker, p0: k }, ...path.slice(i + 1)]) props.setters.pathSaved(false) })} />
@@ -412,7 +424,7 @@ const FlightPlanMap = props => { Repeat positiveSignedIntValidation(v, marker.p2, (k) => { let path = props.getters.path - props.setters.path([...path.slice(0, i), { ...marker, p2: k}, ...path.slice(i + 1)]) + props.setters.path([...path.slice(0, i), { ...marker, p2: k }, ...path.slice(i + 1)]) props.setters.pathSaved(false) })} />
} @@ -426,13 +438,13 @@ const FlightPlanMap = props => { if (p.num == j + 2) { // if starting point of jump is at waypoint to be deleted return null } else if (p.p1 > j + 1) { - return { ...p, p1: p.p1 - 1, cmd: p.cmd, num: p.num - (p.num > j+1 ? 1 : 0) } + return { ...p, p1: p.p1 - 1, cmd: p.cmd, num: p.num - (p.num > j + 1 ? 1 : 0) } } else if (p.p1 == j + 1) { // if destination of jump is to waypoint to be deleted return null // marked for deletion } } - return { ...p, num: (p.num > j+1 ? p.num - 1 : p.num) } + return { ...p, num: (p.num > j + 1 ? p.num - 1 : p.num) } } const _delete = (_p, k) => { @@ -491,7 +503,7 @@ const FlightPlanMap = props => { /> - { /* Need for SUAS: geofence, airdrop, uav, waypoint */ } + { /* Need for SUAS: geofence, airdrop, uav, waypoint */} @@ -508,6 +520,22 @@ const FlightPlanMap = props => { })} + + + + {props.getters.planePoints.map((marker, index) => { + return popup(marker, index, "uavPath") + })} + + + + + + {props.getters.planePoints.map((marker, index) => { + return popup(marker, index, "uavPath") + })} + + {props.getters.uav.heading == null ? null : ( @@ -558,10 +586,10 @@ const FlightPlanMap = props => { return ( <> - {popup({...marker, lng: (props.getters.path[j].lng + props.getters.path[marker.p1 - 1].lng)/2, lat: (props.getters.path[j].lat + props.getters.path[marker.p1 - 1].lat)/2}, marker.num, "jump", ( + {popup({ ...marker, lng: (props.getters.path[j].lng + props.getters.path[marker.p1 - 1].lng) / 2, lat: (props.getters.path[j].lat + props.getters.path[marker.p1 - 1].lat) / 2 }, marker.num, "jump", (
#{i + 1}: Jump
- {MarkerPopup({marker: marker, i: i, datatype: "jump"})} + {MarkerPopup({ marker: marker, i: i, datatype: "jump" })}
), false)} @@ -570,21 +598,21 @@ const FlightPlanMap = props => { return popup(marker, marker.num, "unlim", (
#{i + 1}: Unlimited Loiter
- {MarkerPopup({marker: marker, i: i, datatype: "unlim"})} + {MarkerPopup({ marker: marker, i: i, datatype: "unlim" })}
), true) } else if (marker.cmd === Commands.turnLoiter) { return popup(marker, marker.num, "turn", (
#{i + 1} Turn Loiter
- {MarkerPopup({marker: marker, i: i, datatype: "turn"})} + {MarkerPopup({ marker: marker, i: i, datatype: "turn" })}
), true) } else if (marker.cmd === Commands.timeLoiter) { return popup(marker, marker.num, "time", (
#{i + 1}: Time Loiter
- {MarkerPopup({marker: marker, i: i, datatype: "time"})} + {MarkerPopup({ marker: marker, i: i, datatype: "time" })}
), true) } @@ -592,7 +620,7 @@ const FlightPlanMap = props => { return popup(marker, marker.num, "path", (
#{i + 1}: Mission Path Waypoint
- {MarkerPopup({marker: marker, i: i, datatype: "path"})} + {MarkerPopup({ marker: marker, i: i, datatype: "path" })}
), true) })} diff --git a/client/src/pages/FlightData/index.js b/client/src/pages/FlightData/index.js index b68baa78..0a33ba03 100644 --- a/client/src/pages/FlightData/index.js +++ b/client/src/pages/FlightData/index.js @@ -25,27 +25,27 @@ TODO: Display list highlighting (and vice versa) const FlightData = () => { const [flightBoundary, setFlightBoundary] = useState([ - {lat: 38.31729702009844, lng: -76.55617670782419}, - {lat: 38.31594832826572, lng: -76.55657341657302}, - {lat: 38.31546739500083, lng: -76.55376201277696}, - {lat: 38.31470980862425, lng: -76.54936361414539}, - {lat: 38.31424154692598, lng: -76.54662761646904}, - {lat: 38.31369801280048, lng: -76.54342380058223}, - {lat: 38.31331079191371, lng: -76.54109648475954}, - {lat: 38.31529941346197, lng: -76.54052104837133}, - {lat: 38.31587643291039, lng: -76.54361305817427}, - {lat: 38.31861642463319, lng: -76.54538594175376}, - {lat: 38.31862683616554, lng: -76.55206138505936}, - {lat: 38.31703471119464, lng: -76.55244787859773}, - {lat: 38.31674255749409, lng: -76.55294546866578}, - {lat: 38.31729702009844, lng: -76.55617670782419} + { lat: 38.31729702009844, lng: -76.55617670782419 }, + { lat: 38.31594832826572, lng: -76.55657341657302 }, + { lat: 38.31546739500083, lng: -76.55376201277696 }, + { lat: 38.31470980862425, lng: -76.54936361414539 }, + { lat: 38.31424154692598, lng: -76.54662761646904 }, + { lat: 38.31369801280048, lng: -76.54342380058223 }, + { lat: 38.31331079191371, lng: -76.54109648475954 }, + { lat: 38.31529941346197, lng: -76.54052104837133 }, + { lat: 38.31587643291039, lng: -76.54361305817427 }, + { lat: 38.31861642463319, lng: -76.54538594175376 }, + { lat: 38.31862683616554, lng: -76.55206138505936 }, + { lat: 38.31703471119464, lng: -76.55244787859773 }, + { lat: 38.31674255749409, lng: -76.55294546866578 }, + { lat: 38.31729702009844, lng: -76.55617670782419 } ]) const [airdropBoundary, setAirdropBoundary] = useState([ - {lat: 38.31442311312976, lng: -76.54522971451763}, - {lat: 38.31421041772561, lng: -76.54400246436776}, - {lat: 38.3144070396263, lng: -76.54394394383165}, - {lat: 38.31461622313521, lng: -76.54516993186949}, - {lat: 38.31442311312976, lng: -76.54522971451763} + { lat: 38.31442311312976, lng: -76.54522971451763 }, + { lat: 38.31421041772561, lng: -76.54400246436776 }, + { lat: 38.3144070396263, lng: -76.54394394383165 }, + { lat: 38.31461622313521, lng: -76.54516993186949 }, + { lat: 38.31442311312976, lng: -76.54522971451763 } ]) const [uav, setUav] = useState({}) const [home, setHome] = useState({}) @@ -62,6 +62,8 @@ const FlightData = () => { const [currentDistance, setCurrentDistance] = useState(-1) const [firstJump, setFirstJump] = useState(-1) const [firstPoint, setFirstPoint] = useState(-1) + const [planePoints, setPlanePoints] = useState([]) + const [Awaypoint, setAwaypoint] = useState([]) const getters = { flightBoundary: flightBoundary, @@ -77,7 +79,9 @@ const FlightData = () => { defaultAlt: defaultAlt, currentDistance: currentDistance, firstJump: firstJump, - firstPoint: firstPoint + firstPoint: firstPoint, + planePoints: planePoints, + Awaypoint: Awaypoint } const setters = { @@ -94,7 +98,9 @@ const FlightData = () => { defaultAlt: setDefaultAlt, currentDistance: setCurrentDistance, firstJump: setFirstJump, - firstPoint: setFirstPoint + firstPoint: setFirstPoint, + planePoints: setPlanePoints, + Awaypoint: setAwaypoint } const display = { @@ -107,6 +113,7 @@ const FlightData = () => { time: ["Time Loiter", "Time Loiter"], jump: ["Jump", "Jump"], uav: ["UAV", "UAV Location"], + uavPath: ["UAV Path", "UAV Path"], water: ["Drop", "Bottle Drop Location"] } @@ -127,6 +134,21 @@ const FlightData = () => { lat: response.data.result.home.lat, lng: response.data.result.home.lon }) + setPlanePoints(planePoints => [ + ...planePoints, + { + lat: response.data.result.lat, + lng: response.data.result.lon + } + ]); + }) + httpget("/uav/stats", response => { + + setAwaypoint(Awaypoint => [ + { + num: response.data.result.quick.waypoint[0] + } + ]); }) })