Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
Sensor.cpp
1
5
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "Sensor.h"
8
9#include <iomanip>
10
11#include <QDebug>
12#include <QString>
13
14#include "MathUtils.h"
15
16#include "Angle.h"
17#include "Constants.h"
18#include "CubeManager.h"
19#include "Distance.h"
20#include "EllipsoidShape.h"
21#include "IException.h"
22#include "IString.h"
23#include "iTime.h"
24#include "Latitude.h"
25#include "Longitude.h"
26#include "NaifStatus.h"
27#include "Projection.h"
28#include "ShapeModel.h"
29#include "SpecialPixel.h"
30#include "SurfacePoint.h"
31#include "Target.h"
32#include "UniqueIOCachingAlgorithm.h"
33
34using namespace std;
35
36namespace Isis {
37
45 Sensor::Sensor(Cube &cube) : Spice(cube) {
46 m_newLookB = false;
47 }
48
49
53
54
60 void Sensor::IgnoreElevationModel(bool ignore) {
61 // if we have an elevation model and are not ignoring it,
62 // set p_hasElevationModel to true
63 if (!ignore) {
65 }
66 else {
68 }
69 }
70
71
82
83 QString message = "Pixel Ifov offsets not implemented for this camera.";
84 throw IException(IException::Programmer, message, _FILEINFO_);
85 }
86
87
101
102
141 bool Sensor::SetLookDirection(const double v[3]) {
142 // std::cout << "Sensor::SetLookDirection()\n";
143 // The look vector must be in the camera coordinate system
144
145 // copy v to LookC
146 // lookC[0] = v[0];
147 // lookC[1] = v[1];
148 // lookC[2] = v[2]
149 vector<double> lookC(v, v + 3);
150
151 // Convert it to body-fixed
152 const vector<double> &lookJ = instrumentRotation()->J2000Vector(lookC);
153 const vector<double> &lookB = bodyRotation()->ReferenceVector(lookJ);
154
155 // This memcpy does:
156 // m_lookB[0] = lookB[0];
157 // m_lookB[1] = lookB[1];
158 // m_lookB[2] = lookB[2];
159 memcpy(m_lookB, &lookB[0], sizeof(double) * 3);
160 m_newLookB = true;
161
162 // Don't try to intersect the sky
163 if (target()->isSky()) {
164 target()->shape()->setHasIntersection(false);
165 return false;
166 }
167
168 // See if it intersects the planet
169 const vector<double> &sB = bodyRotation()->ReferenceVector(
171
172 // double tolerance = resolution() / 100.0; return
173 // target()->shape()->intersectSurface(sB, lookB, tolerance);
174 return target()->shape()->intersectSurface(sB, lookB);
175 }
176
177
187 return target()->shape()->hasIntersection();
188 }
189
190
196 void Sensor::Coordinate(double p[3]) const {
197 ShapeModel *shape = target()->shape();
198 p[0] = shape->surfaceIntersection()->GetX().kilometers();
199 p[1] = shape->surfaceIntersection()->GetY().kilometers();
200 p[2] = shape->surfaceIntersection()->GetZ().kilometers();
201 }
202
203
211 return GetLatitude().degrees();
212 }
213
214
224
225
234 return GetLongitude().degrees();
235 }
236
237
248
249
258
259
268 //TODO: We probably need to be validating surface intersect point is not NULL
269 // Here? or in ShapeModel? or what, man?
271 }
272
273
286 return target()->shape()->localRadius(lat, lon);
287 }
288
289
301 Distance Sensor::LocalRadius(double lat, double lon) {
302 return target()->shape()->localRadius(Latitude(lat, Angle::Degrees),
304 }
305
306
312 double Sensor::PhaseAngle() const {
313 double sensorPosBf[3];
314 instrumentBodyFixedPosition(sensorPosBf);
315 double groundPtBf[3];
316 Coordinate(groundPtBf);
317 return RAD2DEG * SensorUtilities::sepAngle(sensorPosBf, groundPtBf, m_uB);
318 }
319
320
326 double Sensor::EmissionAngle() const {
327 return target()->shape()->emissionAngle(
328 bodyRotation()->ReferenceVector(instrumentPosition()->Coordinate()));
329 }
330
331
337 double Sensor::IncidenceAngle() const {
338 std::vector<double> sunB(m_uB, m_uB+3);
339 return target()->shape()->incidenceAngle(sunB);
340 }
341
342
361 bool Sensor::SetUniversalGround(const double latitude,
362 const double longitude,
363 bool backCheck) {
364
365 ShapeModel *shape = target()->shape();
366 shape->clearSurfacePoint();
367
368 // Can't intersect the sky
369 if (target()->isSky()) {
370 return false;
371 }
372
373 // Load the latitude/longitude
374 Latitude lat(latitude, Angle::Degrees);
375 Longitude lon(longitude, Angle::Degrees);
376 // Local radius is deferred to (possible derived) shape model method
377 shape->intersectSurface(lat, lon,
378 bodyRotation()->ReferenceVector(instrumentPosition()->Coordinate()),
379 backCheck);
380
381 return SetGroundLocal(backCheck);
382 }
383
403 bool Sensor::SetUniversalGround(const double latitude,
404 const double longitude,
405 const double radius,
406 bool backCheck) {
407
408 ShapeModel *shape = target()->shape();
409 shape->clearSurfacePoint();
410
411 // Can't intersect the sky
412 if (target()->isSky()) {
413 return false;
414 }
415
416 Latitude lat(latitude, Angle::Degrees);
417 Longitude lon(longitude, Angle::Degrees);
418 Distance rad(radius, Distance::Meters);
419
420 shape->intersectSurface(SurfacePoint(lat, lon, rad),
421 bodyRotation()->ReferenceVector(instrumentPosition()->Coordinate()),
422 backCheck);
423
424 return SetGroundLocal(backCheck);
425 }
426
427
445 bool Sensor::SetGround(const SurfacePoint &surfacePt, bool backCheck) {
446 //std::cout << "Sensor::SetGround()\n";
447 ShapeModel *shape = target()->shape();
448 shape->clearSurfacePoint();
449
450 // Can't intersect the sky
451 if (target()->isSky()) {
452 return false;
453 }
454
455 shape->intersectSurface(surfacePt,
456 bodyRotation()->ReferenceVector(instrumentPosition()->Coordinate()),
457 backCheck);
458
459 return SetGroundLocal(backCheck);
460 }
461
462
477 bool Sensor::SetGroundLocal(bool backCheck) {
478 ShapeModel *shape = target()->shape();
479 // With the 3 spherical value compute the x/y/z coordinate
480 //latrec_c(m_radius, (m_longitude * PI / 180.0), (m_latitude * PI / 180.0), m_pB);
481
482
483 if (!(shape->hasIntersection())) {
484 return false;
485 }
486
487 // Make sure the point isn't on the backside of the body
488
489 // This is static purely for performance reasons. A significant speedup
490 // is achieved here.
491 const vector<double> &sB =
493
494 m_lookB[0] = shape->surfaceIntersection()->GetX().kilometers() - sB[0];
495 m_lookB[1] = shape->surfaceIntersection()->GetY().kilometers() - sB[1];
496 m_lookB[2] = shape->surfaceIntersection()->GetZ().kilometers() - sB[2];
497 m_newLookB = true;
498
499 // See if the point is on the backside of the target. Note occlusion handling
500 // now handles this in derived shape models that can support it. (KJB 2017-03-23)
501 // This may be good if the computation of the look direction is more sophisticated.
502 if (backCheck) {
503 // Assume the intersection point is good in order to get the emission angle
504 // shape->setHasIntersection(true); //KJB there should be a formal intersection in ShapeModel
505 std::vector<double> lookdir = lookDirectionBodyFixed();
506 if ( !shape->isVisibleFrom(sB, lookdir) ) {
507 shape->clearSurfacePoint();
508 shape->setHasIntersection(false);
509 return false;
510 }
511 }
512
513 // return with success
514 shape->setHasIntersection(true);
515
516 return true;
517 }
518
519
525 void Sensor::LookDirection(double v[3]) const {
526 vector<double> lookC = instrumentRotation()->ReferenceVector(lookDirectionJ2000());
527 v[0] = lookC[0];
528 v[1] = lookC[1];
529 v[2] = lookC[2];
530 }
531
537 vector<double> Sensor::lookDirectionBodyFixed() const {
538 vector<double> lookB(3);
539 lookB[0] = m_lookB[0];
540 lookB[1] = m_lookB[1];
541 lookB[2] = m_lookB[2];
542 return lookB;
543 }
544
545
551 vector<double> Sensor::lookDirectionJ2000() const {
552 vector<double> lookJ = bodyRotation()->J2000Vector(lookDirectionBodyFixed());
553 return lookJ;
554 }
555
556
557
564 if (m_newLookB) {
565 computeRaDec();
566 }
567 return m_ra;
568 }
569
570
577 if (m_newLookB) {
578 computeRaDec();
579 }
580 return m_dec;
581 }
582
583
588 m_newLookB = false;
589 vector<double> lookB = {m_lookB[0], m_lookB[1], m_lookB[2]};
590 vector<double> lookJ = bodyRotation()->J2000Vector(lookB);
591
592 SensorUtilities::GroundPt3D sphericalPt = SensorUtilities::rectToSpherical(&lookJ[0]);
593 m_ra = sphericalPt.lon;
594 // Convert to [0, 2pi] domain
595 if (m_ra < 0) {
596 m_ra += 2 * PI;
597 }
598 m_ra *= RAD2DEG;
599 m_dec = sphericalPt.lat * RAD2DEG;
600 }
601
602
611 bool Sensor::SetRightAscensionDeclination(const double ra, const double dec) {
612 double raRad = ra * DEG2RAD;
613 double decRad = dec * DEG2RAD;
614
615 // Make the radius bigger, some multiple of the body radius -or- use sensor position at the reference point
616 SensorUtilities::GroundPt3D sphericalPt = {decRad, raRad, 1};
617 SensorUtilities::Vec rectPt = SensorUtilities::sphericalToRect(sphericalPt);
618
619 vector<double> lookC = instrumentRotation()->ReferenceVector(rectPt);
620 return SetLookDirection(&lookC[0]);
621 }
622
623
632 void Sensor::SpacecraftSurfaceVector(double scSurfaceVector[3]) const {
633 scSurfaceVector[0] = m_lookB[0];
634 scSurfaceVector[1] = m_lookB[1];
635 scSurfaceVector[2] = m_lookB[2];
636 }
637
638
644 double Sensor::SlantDistance() const {
645 double sensorPos[3];
647
648 SurfacePoint *surfPoint = target()->shape()->surfaceIntersection();
649 SensorUtilities::Vec groundPt = {
650 surfPoint->GetX().kilometers(),
651 surfPoint->GetY().kilometers(),
652 surfPoint->GetZ().kilometers()};
653
654 return SensorUtilities::distance(sensorPos, groundPt);
655 }
656
657
664 double slat, slon;
665 subSolarPoint(slat, slon);
666
667 double lst = UniversalLongitude() - slon + 180.0;
668 lst = lst / 15.0; // 15 degress per hour
669 if (lst < 0.0) lst += 24.0;
670 if (lst > 24.0) lst -= 24.0;
671 return lst;
672 }
673
674
680 double Sensor::SolarDistance() const {
681 // Get the sun coord
682 double sB[3];
684
685 SurfacePoint *intersection = target()->shape()->surfaceIntersection();
686 SensorUtilities::Vec groundPt = {
687 intersection->GetX().kilometers(),
688 intersection->GetY().kilometers(),
689 intersection->GetZ().kilometers()};
690
691 return SensorUtilities::distance(groundPt, sB) / 149597870.691;
692 }
693
694
702 // Get the spacecraft coord
703 double sensorPos[3];
704 Spice::instrumentPosition(sensorPos);
705
706 // Get subspacecraft point
707 double lat, lon;
708 subSpacecraftPoint(lat, lon);
709
710 // Compute radius
711 Distance rad = LocalRadius(lat, lon);
712
713 // Take the difference
714 return SensorUtilities::magnitude(sensorPos) - rad.kilometers();
715 }
716}
double degrees() const
Get the angle in units of Degrees.
Definition Angle.h:232
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition Angle.h:56
IO Handler for Isis Cubes.
Definition Cube.h:168
double kilometers() const
Get the displacement in kilometers.
Distance measurement, usually in meters.
Definition Distance.h:34
double kilometers() const
Get the distance in kilometers.
Definition Distance.cpp:106
@ Meters
The distance is being specified in meters.
Definition Distance.h:43
This class is designed to encapsulate the concept of a Latitude.
Definition Latitude.h:51
This class is designed to encapsulate the concept of a Longitude.
Definition Longitude.h:40
void setTime(const iTime &time)
By setting the time you essential set the position of the spacecraft and body as indicated in the cla...
Definition Sensor.cpp:97
virtual SurfacePoint GetSurfacePoint() const
Returns the surface point (most efficient accessor).
Definition Sensor.cpp:255
bool SetUniversalGround(const double latitude, const double longitude, bool backCheck=true)
This is the opposite routine for SetLookDirection.
Definition Sensor.cpp:361
double LocalSolarTime()
Return the local solar time in hours.
Definition Sensor.cpp:663
SpiceDouble m_lookB[3]
Look direction in body fixed.
Definition Sensor.h:234
SpiceDouble m_dec
Decliation (sky latitude)
Definition Sensor.h:242
virtual double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
Definition Sensor.cpp:210
virtual double RightAscension()
Returns the right ascension angle (sky longitude).
Definition Sensor.cpp:563
Longitude GetLongitude() const
Returns a positive east, 0-360 domain longitude object at the surface intersection point in the body ...
Definition Sensor.cpp:245
virtual double SolarDistance() const
Returns the distance between the sun and surface point in AU.
Definition Sensor.cpp:680
bool HasSurfaceIntersection() const
Returns if the last call to either SetLookDirection or SetUniversalGround had a valid intersection wi...
Definition Sensor.cpp:186
virtual double SlantDistance() const
Return the distance between the spacecraft and surface point in kmv.
Definition Sensor.cpp:644
void SpacecraftSurfaceVector(double scSurfaceVector[3]) const
Sets the vector between the spacecraft and surface point in body-fixed.
Definition Sensor.cpp:632
bool m_newLookB
flag to indicate we need to recompute ra/dec
Definition Sensor.h:235
virtual QList< QPointF > PixelIfovOffsets()
This method is implemented in Camera which defaults to the (pixel pitch * summing mode ) / 2.
Definition Sensor.cpp:81
Latitude GetLatitude() const
Returns a planetocentric latitude object at the surface intersection point in body fixed.
Definition Sensor.cpp:221
SpiceDouble m_ra
Right ascension (sky longitude)
Definition Sensor.h:241
double SpacecraftAltitude()
Returns the distance from the spacecraft to the subspacecraft point in km.
Definition Sensor.cpp:701
virtual ~Sensor()
Destroys the Sensor.
Definition Sensor.cpp:51
virtual std::vector< double > lookDirectionBodyFixed() const
Returns the look direction in the body fixed coordinate system.
Definition Sensor.cpp:537
bool SetGround(const SurfacePoint &surfacePt, bool backCheck=true)
This overloaded method has the opposite function as SetLookDirection.
Definition Sensor.cpp:445
bool SetGroundLocal(bool backCheck)
Computes look vector.
Definition Sensor.cpp:477
virtual std::vector< double > lookDirectionJ2000() const
Returns the look direction in the camera coordinate system.
Definition Sensor.cpp:551
void IgnoreElevationModel(bool ignore)
This allows you to ignore the cube elevation model and use the ellipse.
Definition Sensor.cpp:60
virtual double PhaseAngle() const
Returns the phase angle in degrees.
Definition Sensor.cpp:312
bool SetRightAscensionDeclination(const double ra, const double dec)
Given the ra/dec compute the look direction.
Definition Sensor.cpp:611
virtual double IncidenceAngle() const
Returns the incidence angle in degrees.
Definition Sensor.cpp:337
virtual double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
Definition Sensor.cpp:233
void Coordinate(double p[3]) const
Returns the x,y,z of the surface intersection in BodyFixed km.
Definition Sensor.cpp:196
Sensor(Cube &cube)
Constructs a Sensor object and loads SPICE kernels using information from the label object.
Definition Sensor.cpp:45
Distance LocalRadius() const
Returns the local radius at the intersection point.
Definition Sensor.cpp:267
virtual double Declination()
Returns the declination angle (sky latitude).
Definition Sensor.cpp:576
virtual double EmissionAngle() const
Returns the emission angle in degrees.
Definition Sensor.cpp:326
void LookDirection(double v[3]) const
Returns the look direction in the camera coordinate system.
Definition Sensor.cpp:525
bool SetLookDirection(const double v[3])
Sets the look direction of the spacecraft.
Definition Sensor.cpp:141
void computeRaDec()
Computes the ra/dec from the look direction.
Definition Sensor.cpp:587
Define shapes and provide utilities for Isis targets.
Definition ShapeModel.h:65
virtual void clearSurfacePoint()
Clears or resets the current surface point.
bool hasIntersection()
Returns intersection status.
void setHasIntersection(bool b)
Sets the flag to indicate whether this ShapeModel has an intersection.
virtual SurfacePoint * surfaceIntersection() const
Returns the surface intersection for this ShapeModel.
virtual double emissionAngle(const std::vector< double > &sB)
Computes and returns emission angle, in degrees, given the observer position.
virtual bool isVisibleFrom(const std::vector< double > observerPos, const std::vector< double > lookDirection)
Default occulsion implementation.
virtual double incidenceAngle(const std::vector< double > &uB)
Computes and returns incidence angle, in degrees, given the illuminator position.
virtual void setTime(const iTime &time)
Sets the ephemeris time and reads the spacecraft and sun position from the kernels at that instant in...
Definition Spice.cpp:997
Spice(Cube &cube)
Constructs a Spice object and loads SPICE kernels using information from the label object.
Definition Spice.cpp:65
virtual SpiceRotation * bodyRotation() const
Accessor method for the body rotation.
Definition Spice.cpp:1833
virtual void subSolarPoint(double &lat, double &lon)
Returns the sub-solar latitude/longitude in universal coordinates (0-360 positive east,...
Definition Spice.cpp:1551
virtual void instrumentBodyFixedPosition(double p[3]) const
Returns the spacecraft position in body-fixed frame km units.
Definition Spice.cpp:1052
virtual Target * target() const
Returns a pointer to the target object.
Definition Spice.cpp:1590
virtual iTime time() const
Returns the ephemeris time in seconds which was used to obtain the spacecraft and sun positions.
Definition Spice.cpp:1101
virtual SpiceRotation * instrumentRotation() const
Accessor method for the instrument rotation.
Definition Spice.cpp:1844
virtual SpicePosition * instrumentPosition() const
Accessor method for the instrument position.
Definition Spice.cpp:1822
SpiceDouble m_uB[3]
This contains the sun position (u) in the bodyfixed reference frame (B).
Definition Spice.h:371
virtual SpicePosition * sunPosition() const
Accessor method for the sun position.
Definition Spice.cpp:1811
virtual void subSpacecraftPoint(double &lat, double &lon)
Returns the sub-spacecraft latitude/longitude in universal coordinates (0-360 positive east,...
Definition Spice.cpp:1500
std::vector< double > ReferenceVector(const std::vector< double > &jVec)
Given a direction vector in J2000, return a reference frame direction.
std::vector< double > J2000Vector(const std::vector< double > &rVec)
Given a direction vector in the reference frame, return a J2000 direction.
This class defines a body-fixed surface point.
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
Distance GetLocalRadius() const
Return the radius of the surface point.
void setShapeEllipsoid()
Set the shape to the ellipsoid and save the original shape.
Definition Target.cpp:628
ShapeModel * shape() const
Return the shape.
Definition Target.cpp:680
void restoreShape()
Restores the shape to the original after setShapeEllipsoid has overridden it.
Definition Target.cpp:610
Parse and return pieces of a time string.
Definition iTime.h:65
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
Namespace for the standard library.