4#include <isce3/core/Basis.h>
5#include <isce3/core/Ellipsoid.h>
6#include <isce3/core/Orbit.h>
7#include <isce3/core/Pixel.h>
8#include <isce3/core/Vector.h>
9#include <isce3/math/RootFind1dBracket.h>
13NVCC_HD_WARNING_DISABLE
14template<
class Orbit,
class DEMInterpolator>
15CUDA_HOSTDEV isce3::error::ErrorCode
16rdr2geo(isce3::core::Vec3* llh,
double t,
double r,
double fd,
17 const Orbit& orbit,
const DEMInterpolator& dem,
18 const isce3::core::Ellipsoid& ellipsoid,
double wvl,
19 isce3::core::LookSide side,
double h0,
const Rdr2GeoParams& params)
21 using namespace isce3::core;
22 using isce3::error::ErrorCode;
27 orbit.
interpolate(&pos, &vel, t, OrbitInterpBorderMode::FillNaN);
28 if (status != ErrorCode::Success) {
33 const auto tcnbasis = Basis(pos, vel);
36 const auto vmag = vel.norm();
37 const auto dopfact = 0.5 * wvl * fd * r / vmag;
39 const auto pixel = Pixel(r, dopfact, 0);
40 return rdr2geo(llh, pixel, tcnbasis, pos, vel, dem, ellipsoid, side, h0,
44NVCC_HD_WARNING_DISABLE
45template<
class DEMInterpolator>
46CUDA_HOSTDEV isce3::error::ErrorCode
47rdr2geo(isce3::core::Vec3* llh,
const isce3::core::Pixel& pixel,
48 const isce3::core::Basis& tcnbasis,
const isce3::core::Vec3& pos,
49 const isce3::core::Vec3& vel,
const DEMInterpolator& dem,
50 const isce3::core::Ellipsoid& ellipsoid, isce3::core::LookSide side,
53 using namespace isce3::core;
54 using isce3::error::ErrorCode;
57 const auto vhat = vel.normalized();
60 const auto& that = tcnbasis.
x0();
61 const auto& chat = tcnbasis.
x1();
62 const auto& nhat = tcnbasis.
x2();
65 const auto ndotv = nhat.dot(vhat);
66 const auto vdott = vhat.dot(that);
69 const auto major = ellipsoid.
a();
70 const auto minor = major * std::sqrt(1. - ellipsoid.
e2());
73 const auto sat_dist = pos.norm();
74 const auto eta = [&]() {
75 const auto x = pos[0] / major;
76 const auto y = pos[1] / major;
77 const auto z = pos[2] / minor;
78 return 1. / std::sqrt((x * x) + (y * y) + (z * z));
80 const auto radius = eta * sat_dist;
81 const auto height = (1. - eta) * sat_dist;
85 auto updateLLH = [&](
const double h) {
87 const auto a = sat_dist;
88 const auto b = radius + h;
89 const auto cos_theta = 0.5 * (a / pixel.range() + pixel.range() / a -
90 (b / a) * (b / pixel.range()));
91 const auto sin_theta = std::sqrt(1. - cos_theta * cos_theta);
94 const auto gamma = pixel.range() * cos_theta;
95 const auto alpha = (pixel.dopfact() - gamma * ndotv) / vdott;
96 const auto beta = [&]() {
97 const auto x = pixel.range() * sin_theta;
98 const auto beta = std::sqrt((x * x) - (alpha * alpha));
99 return (side == LookSide::Right) ? beta : -beta;
103 const auto delta = alpha * that + beta * chat + gamma * nhat;
106 const auto xyz = pos + delta;
111 bool converged =
false;
112 auto h = std::isnan(h0) ? height : h0;
114 for (
int i = 0; i < params.maxiter + params.extraiter; ++i) {
117 if (height - h >= pixel.range()) {
122 auto llh_new = updateLLH(h);
128 const auto xyz_new = ellipsoid.
lonLatToXyz(llh_new);
131 h = xyz_new.norm() - radius;
134 const auto r = (pos - xyz_new).norm();
135 const auto dr = std::abs(pixel.range() - r);
136 if (dr < params.threshold) {
143 if (i > params.maxiter) {
144 const auto xyz_old = ellipsoid.
lonLatToXyz(llh_old);
145 const auto xyz_avg = 0.5 * (xyz_old + xyz_new);
147 h = xyz_avg.norm() - radius;
168 return converged ? ErrorCode::Success : ErrorCode::FailedToConverge;
172NVCC_HD_WARNING_DISABLE
173template<
class Orbit,
class DEMInterpolator>
174CUDA_HOSTDEV isce3::error::ErrorCode
175rdr2geo_bracket(isce3::core::Vec3* xyz,
176 double aztime,
double slantRange,
double doppler,
const Orbit& orbit,
177 const DEMInterpolator& dem,
const isce3::core::Ellipsoid& ellipsoid,
178 double wavelength, isce3::core::LookSide side,
181 using namespace isce3::core;
182 using isce3::error::ErrorCode;
185 Vec3 radarXYZ, velocity;
186 const auto errCode = orbit.
interpolate(&radarXYZ, &velocity, aztime);
187 if (errCode != ErrorCode::Success) {
190 const double speed = velocity.norm();
195 const Vec3 alongTrack = velocity / speed;
196 const Vec3 right = alongTrack.cross(radarXYZ).normalized();
197 const Vec3 down = alongTrack.cross(right);
198 const Vec3 horizontal = (side == LookSide::Right) ? right : -right;
201 const double sinSquint = doppler * wavelength / (2 * speed);
203 const double cosSquint = std::sqrt(1.0 - sinSquint * sinSquint);
207 const Vec3 center = radarXYZ + sinSquint * slantRange * alongTrack;
208 const double radius = cosSquint * slantRange;
211 auto getXYZ = [&](
double look) {
212 return center + radius * std::sin(look) * horizontal +
213 radius * std::cos(look) * down;
223 auto dh = [&](
double look) {
224 const Vec3 xyz = getXYZ(look);
231 const double tolLook = params.tol_height / radius;
234 double lookSolution = 0.0;
235 const auto err = isce3::math::find_zero_brent(
236 params.look_min, params.look_max, dh, tolLook, &lookSolution);
237 if (err != ErrorCode::Success) {
240 *xyz = getXYZ(lookSolution);
241 return ErrorCode::Success;
double interpolateLonLat(double lon, double lat) const
Interpolate at a given longitude and latitude.
Definition DEMInterpolator.cpp:593
isce3::error::ErrorCode interpolate(Vec3 *position, Vec3 *velocity, double t, OrbitInterpBorderMode border_mode=OrbitInterpBorderMode::Error) const
Interpolate platform position and/or velocity.
Definition Orbit.cpp:71
CUDA_HOSTDEV const Vec3 & x2() const
Return third basis vector.
Definition Basis.h:67
CUDA_HOSTDEV const Vec3 & x0() const
Return first basis vector.
Definition Basis.h:61
CUDA_HOSTDEV const Vec3 & x1() const
Return second basis vector.
Definition Basis.h:64
CUDA_HOSTDEV void xyzToLonLat(const cartesian_t &xyz, cartesian_t &llh) const
Transform ECEF xyz to Lon/Lat/Hgt.
Definition Ellipsoid.h:197
CUDA_HOSTDEV double a() const
Return semi-major axis.
Definition Ellipsoid.h:38
CUDA_HOSTDEV double e2() const
Return eccentricity^2.
Definition Ellipsoid.h:46
CUDA_HOSTDEV void lonLatToXyz(const cartesian_t &llh, cartesian_t &xyz) const
Transform WGS84 Lon/Lat/Hgt to ECEF xyz.
Definition Ellipsoid.h:178
The isce3::geometry namespace.
Definition boundingbox.h:15
base interpolator is an abstract base class
Definition BinarySearchFunc.cpp:5