4#include <isce3/core/Ellipsoid.h>
5#include <isce3/core/Orbit.h>
6#include <isce3/core/Vector.h>
7#include <isce3/math/RootFind1dBracket.h>
9namespace isce3::geometry::detail {
11NVCC_HD_WARNING_DISABLE
12template<
class DopplerModel>
13CUDA_HOSTDEV isce3::error::ErrorCode
14computeDopplerAztimeDiff(
double* dt,
double t,
double r,
15 const isce3::core::Vec3& rvec,
16 const isce3::core::Vec3& vel,
17 const DopplerModel& doppler,
double wvl,
double dr)
19 using isce3::error::ErrorCode;
23 if (doppler.boundsError()) {
24 if (not(doppler.contains(t, r) and doppler.contains(t, r + dr))) {
25 return ErrorCode::OutOfBoundsLookup;
30 const auto dopfact = rvec.dot(vel);
31 const auto fdop = 0.5 * wvl * doppler.eval(t, r);
34 const auto fdopder = (0.5 * wvl * doppler.eval(t, r + dr) - fdop) / dr;
37 const auto fn = dopfact - fdop * r;
38 const auto c1 = -vel.dot(vel);
39 const auto c2 = (fdop / r) + fdopder;
40 const auto fnprime = c1 + c2 * dopfact;
47 return ErrorCode::Success;
50NVCC_HD_WARNING_DISABLE
52CUDA_HOSTDEV isce3::error::ErrorCode
53updateAztime(
double* t,
const Orbit& orbit,
const isce3::core::Vec3& xyz,
54 isce3::core::LookSide side,
55 double rmin = std::numeric_limits<double>::quiet_NaN(),
56 double rmax = std::numeric_limits<double>::quiet_NaN())
58 using namespace isce3::core;
59 using isce3::error::ErrorCode;
62 constexpr static int num_aztime_test = 15;
64 const auto tend = orbit.
endTime();
65 const auto dt = (tend - tstart) / (num_aztime_test - 1);
68 double r_closest = 1e16;
69 double t_closest = -1000.;
70 for (
int k = 0; k < num_aztime_test; ++k) {
72 const auto tt = tstart + k * dt;
73 if (tt < tstart or tt > tend) {
79 orbit.
interpolate(&pos, &vel, tt, OrbitInterpBorderMode::FillNaN);
82 const auto rvec = xyz - pos;
87 if ((side == LookSide::Right) xor (rvec.cross(vel).dot(pos) > 0.)) {
88 return ErrorCode::WrongLookSide;
92 const auto r = rvec.norm();
95 if (not std::isnan(rmin) and r < rmin) {
98 if (not std::isnan(rmax) and r > rmax) {
110 *t = (t_closest < 0.) ? orbit.
midTime() : t_closest;
111 return ErrorCode::Success;
114NVCC_HD_WARNING_DISABLE
115template<
class Orbit,
class DopplerModel>
116CUDA_HOSTDEV isce3::error::ErrorCode
117geo2rdr(
double* t,
double* r,
const isce3::core::Vec3& llh,
118 const isce3::core::Ellipsoid& ellipsoid,
const Orbit& orbit,
119 const DopplerModel& doppler,
double wvl, isce3::core::LookSide side,
122 using namespace isce3::core;
123 using isce3::error::ErrorCode;
134 const auto status = updateAztime(t, orbit, xyz, side);
135 if (status != ErrorCode::Success) {
144 for (
int i = 0; i < params.maxiter; ++i) {
150 orbit.
interpolate(&pos, &vel, *t, OrbitInterpBorderMode::FillNaN);
153 const auto rvec = xyz - pos;
159 if ((side == LookSide::Right) xor (rvec.cross(vel).dot(pos) > 0.)) {
160 return ErrorCode::WrongLookSide;
165 const auto status = computeDopplerAztimeDiff(&dt, *t, *r, rvec, vel,
166 doppler, wvl, params.delta_range);
167 if (status != ErrorCode::Success) {
172 if (std::abs(dt) < params.threshold) {
173 return ErrorCode::Success;
178 return ErrorCode::FailedToConverge;
182NVCC_HD_WARNING_DISABLE
183template<
class Orbit,
class DopplerModel>
184CUDA_HOSTDEV isce3::error::ErrorCode
185geo2rdr_bracket(
double* aztime,
186 double* range,
const isce3::core::Vec3& x,
const Orbit& orbit,
187 const DopplerModel& doppler,
double wavelength,
190 using namespace isce3::core;
191 using isce3::error::ErrorCode;
193 const double t0 = params.time_start.value_or([&]() {
194 if (doppler.haveData()) {
195 return std::max(orbit.
startTime(), doppler.yStart());
199 const double t1 = params.time_end.value_or([&]() {
200 if (doppler.haveData()) {
201 return std::min(orbit.
endTime(), doppler.yEnd());
211 auto doppler_error = [&](
double t) {
212 orbit.
interpolate(&xp, &v, t, OrbitInterpBorderMode::FillNaN);
214 const double rnorm = r.norm();
215 double fd = doppler.eval(t, rnorm);
216 return 2.0 / wavelength * v.dot(r) / rnorm - fd;
219 const auto err = isce3::math::find_zero_brent(
220 t0, t1, doppler_error, params.tol_aztime, aztime);
221 if (err != ErrorCode::Success) {
226 orbit.
interpolate(&xp, &v, *aztime, OrbitInterpBorderMode::FillNaN);
232 if ((side == LookSide::Right) ^ (r.cross(v).dot(xp) > 0)) {
233 return ErrorCode::WrongLookSide;
235 return ErrorCode::Success;
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
double startTime() const
Time of first state vector relative to reference epoch (s)
Definition Orbit.h:128
double endTime() const
Time of last state vector relative to reference epoch (s)
Definition Orbit.h:134
double midTime() const
Time of center of orbit relative to reference epoch (s)
Definition Orbit.h:131
CUDA_HOSTDEV void lonLatToXyz(const cartesian_t &llh, cartesian_t &xyz) const
Transform WGS84 Lon/Lat/Hgt to ECEF xyz.
Definition Ellipsoid.h:178