[Imagery] Update to be compatible with VIPER (#3744)

* heading, sun heading, and camera pan  are all absolute directions
* removing roll and pitch keys as they will not be necessary
* proofing against empty historical or realtime ids from config
* adding checks in imagerylayout for missing properties

Co-authored-by: Jamie Vigliotta <jamie.j.vigliotta@nasa.gov>
This commit is contained in:
David Tsay 2021-03-08 15:27:35 -08:00 committed by GitHub
parent bffe79ecbd
commit cfaaf6b1fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 58 deletions

View File

@ -27,7 +27,6 @@
> >
<CompassHUD <CompassHUD
v-if="hasCameraFieldOfView" v-if="hasCameraFieldOfView"
:heading="heading"
:sun-heading="sunHeading" :sun-heading="sunHeading"
:camera-angle-of-view="cameraAngleOfView" :camera-angle-of-view="cameraAngleOfView"
:camera-pan="cameraPan" :camera-pan="cameraPan"
@ -79,26 +78,20 @@ export default {
}, },
computed: { computed: {
hasCameraFieldOfView() { hasCameraFieldOfView() {
return this.heading !== undefined && this.cameraPan !== undefined; return this.cameraPan !== undefined && this.cameraAngleOfView > 0;
}, },
// compass direction from north in degrees // horizontal rotation from north in degrees
heading() { heading() {
return this.image.heading; return this.image.heading;
}, },
pitch() { // horizontal rotation from north in degrees
return this.image.pitch;
},
// compass direction from north in degrees
sunHeading() { sunHeading() {
return this.image.sunOrientation; return this.image.sunOrientation;
}, },
// relative direction from heading in degrees // horizontal rotation from north in degrees
cameraPan() { cameraPan() {
return this.image.cameraPan; return this.image.cameraPan;
}, },
cameraTilt() {
return this.image.cameraTilt;
},
cameraAngleOfView() { cameraAngleOfView() {
return CAMERA_ANGLE_OF_VIEW; return CAMERA_ANGLE_OF_VIEW;
}, },

View File

@ -94,10 +94,6 @@ const COMPASS_POINTS = [
export default { export default {
props: { props: {
heading: {
type: Number,
required: true
},
sunHeading: { sunHeading: {
type: Number, type: Number,
default: undefined default: undefined
@ -136,8 +132,8 @@ export default {
}, },
visibleRange() { visibleRange() {
return [ return [
rotate(this.heading, this.cameraPan, -this.cameraAngleOfView / 2), rotate(this.cameraPan, -this.cameraAngleOfView / 2),
rotate(this.heading, this.cameraPan, this.cameraAngleOfView / 2) rotate(this.cameraPan, this.cameraAngleOfView / 2)
]; ];
} }
} }

View File

@ -27,7 +27,7 @@
> >
<div <div
class="c-nsew" class="c-nsew"
:style="rotateFrameStyle" :style="compassRoseStyle"
> >
<svg <svg
class="c-nsew__minor-ticks" class="c-nsew__minor-ticks"
@ -118,21 +118,21 @@
</div> </div>
<div <div
v-if="hasHeading"
class="c-spacecraft-body" class="c-spacecraft-body"
:style="headingStyle" :style="headingStyle"
> >
</div> </div>
<div <div
v-if="showSunHeading" v-if="hasSunHeading"
class="c-sun" class="c-sun"
:style="sunHeadingStyle" :style="sunHeadingStyle"
></div> ></div>
<div <div
v-if="showCameraFOV"
class="c-cam-field" class="c-cam-field"
:style="cameraHeadingStyle" :style="cameraPanStyle"
> >
<div class="cam-field-half cam-field-half-l"> <div class="cam-field-half cam-field-half-l">
<div <div
@ -177,16 +177,10 @@ export default {
} }
}, },
computed: { computed: {
cameraHeading() {
return rotate(this.heading, this.cameraPan);
},
compassHeading() {
return this.lockCompass ? this.cameraHeading : 0;
},
north() { north() {
return rotate(this.compassHeading, -this.cameraHeading); return this.lockCompass ? rotate(-this.cameraPan) : 0;
}, },
rotateFrameStyle() { compassRoseStyle() {
return { transform: `rotate(${ this.north }deg)` }; return { transform: `rotate(${ this.north }deg)` };
}, },
northTextTransform() { northTextTransform() {
@ -216,6 +210,9 @@ export default {
west: `translate(50,87) ${ rotation }` west: `translate(50,87) ${ rotation }`
}; };
}, },
hasHeading() {
return this.heading !== undefined;
},
headingStyle() { headingStyle() {
const rotation = rotate(this.north, this.heading); const rotation = rotate(this.north, this.heading);
@ -223,14 +220,7 @@ export default {
transform: `translateX(-50%) rotate(${ rotation }deg)` transform: `translateX(-50%) rotate(${ rotation }deg)`
}; };
}, },
cameraHeadingStyle() { hasSunHeading() {
const rotation = rotate(this.north, this.cameraHeading);
return {
transform: `rotate(${ rotation }deg)`
};
},
showSunHeading() {
return this.sunHeading !== undefined; return this.sunHeading !== undefined;
}, },
sunHeadingStyle() { sunHeadingStyle() {
@ -240,18 +230,22 @@ export default {
transform: `rotate(${ rotation }deg)` transform: `rotate(${ rotation }deg)`
}; };
}, },
showCameraFOV() { cameraPanStyle() {
return this.cameraPan !== undefined && this.cameraAngleOfView > 0; const rotation = rotate(this.north, this.cameraPan);
return {
transform: `rotate(${ rotation }deg)`
};
}, },
// left half of camera field of view // left half of camera field of view
// rotated counter-clockwise from camera field of view heading // rotated counter-clockwise from camera pan angle
cameraFOVStyleLeftHalf() { cameraFOVStyleLeftHalf() {
return { return {
transform: `translateX(50%) rotate(${ -this.cameraAngleOfView / 2 }deg)` transform: `translateX(50%) rotate(${ -this.cameraAngleOfView / 2 }deg)`
}; };
}, },
// right half of camera field of view // right half of camera field of view
// rotated clockwise from camera field of view heading // rotated clockwise from camera pan angle
cameraFOVStyleRightHalf() { cameraFOVStyleRightHalf() {
return { return {
transform: `translateX(-50%) rotate(${ this.cameraAngleOfView / 2 }deg)` transform: `translateX(-50%) rotate(${ this.cameraAngleOfView / 2 }deg)`

View File

@ -1,23 +1,28 @@
export function rotate(direction, ...rotations) { /**
*
* sums an arbitrary number of absolute rotations
* (meaning rotations relative to one common direction 0)
* normalizes the rotation to the range [0, 360)
*
* @param {...number} rotations in degrees
* @returns {number} normalized sum of all rotations - [0, 360) degrees
*/
export function rotate(...rotations) {
const rotation = rotations.reduce((a, b) => a + b, 0); const rotation = rotations.reduce((a, b) => a + b, 0);
return normalizeCompassDirection(direction + rotation); return normalizeCompassDirection(rotation);
}
export function normalizeCompassDirection(degrees) {
const base = degrees % 360;
return base >= 0 ? base : 360 + base;
} }
export function inRange(degrees, [min, max]) { export function inRange(degrees, [min, max]) {
const point = rotate(degrees);
return min > max return min > max
? (degrees >= min && degrees < 360) || (degrees <= max && degrees >= 0) ? (point >= min && point < 360) || (point <= max && point >= 0)
: degrees >= min && degrees <= max; : point >= min && point <= max;
} }
export function percentOfRange(degrees, [min, max]) { export function percentOfRange(degrees, [min, max]) {
let distance = degrees; let distance = rotate(degrees);
let minRange = min; let minRange = min;
let maxRange = max; let maxRange = max;
@ -31,3 +36,9 @@ export function percentOfRange(degrees, [min, max]) {
return (distance - minRange) / (maxRange - minRange); return (distance - minRange) / (maxRange - minRange);
} }
function normalizeCompassDirection(degrees) {
const base = degrees % 360;
return base >= 0 ? base : 360 + base;
}

View File

@ -348,7 +348,7 @@ export default {
// related telemetry keys // related telemetry keys
this.spacecraftPositionKeys = ['positionX', 'positionY', 'positionZ']; this.spacecraftPositionKeys = ['positionX', 'positionY', 'positionZ'];
this.spacecraftOrientationKeys = ['heading', 'roll', 'pitch']; this.spacecraftOrientationKeys = ['heading'];
this.cameraKeys = ['cameraPan', 'cameraTilt']; this.cameraKeys = ['cameraPan', 'cameraTilt'];
this.sunKeys = ['sunOrientation']; this.sunKeys = ['sunOrientation'];
@ -468,7 +468,12 @@ export default {
// set data ON image telemetry as well as in focusedImageRelatedTelemetry // set data ON image telemetry as well as in focusedImageRelatedTelemetry
for (let key of this.relatedTelemetry.keys) { for (let key of this.relatedTelemetry.keys) {
if (this.relatedTelemetry[key] && this.relatedTelemetry[key].historical) { if (
this.relatedTelemetry[key]
&& this.relatedTelemetry[key].historical
&& this.relatedTelemetry[key].requestLatestFor
) {
let valuesOnTelemetry = this.relatedTelemetry[key].hasTelemetryOnDatum; let valuesOnTelemetry = this.relatedTelemetry[key].hasTelemetryOnDatum;
let value = await this.getMostRecentRelatedTelemetry(key, this.focusedImage); let value = await this.getMostRecentRelatedTelemetry(key, this.focusedImage);

View File

@ -73,7 +73,7 @@ export default class RelatedTelemetry {
await this._initializeHistorical(key); await this._initializeHistorical(key);
} }
if (this[key].realtime && this[key].realtime.telemetryObjectId) { if (this[key].realtime && this[key].realtime.telemetryObjectId && this[key].realtime.telemetryObjectId !== '') {
await this._intializeRealtime(key); await this._intializeRealtime(key);
} }
} }
@ -82,7 +82,9 @@ export default class RelatedTelemetry {
} }
async _initializeHistorical(key) { async _initializeHistorical(key) {
if (this[key].historical.telemetryObjectId) { if (!this[key].historical.telemetryObjectId) {
this[key].historical.hasTelemetryOnDatum = true;
} else if (this[key].historical.telemetryObjectId !== '') {
this[key].historicalDomainObject = await this._openmct.objects.get(this[key].historical.telemetryObjectId); this[key].historicalDomainObject = await this._openmct.objects.get(this[key].historical.telemetryObjectId);
this[key].requestLatestFor = async (datum) => { this[key].requestLatestFor = async (datum) => {
@ -96,8 +98,6 @@ export default class RelatedTelemetry {
return results[results.length - 1]; return results[results.length - 1];
}; };
} else {
this[key].historical.hasTelemetryOnDatum = true;
} }
} }