Repository navigation
Conversation
alexanderbock
left a comment
There was a problem hiding this comment.
I'm not sure why we'd need two sets of functions that basicallyt do the same thing. I think the globebrowsing functions could move into the spicemanager_lua and become the only functions we'll need
| * \\param lat_deg Latitude in degrees | ||
| * \\param lon_deg Longitude in degrees | ||
| * \\param utc_date UTC date as a string (e.g., "2024-01-01") | ||
| * \\param observer The observing body (e.g., "EARTH") | ||
| * \\param isSunrise If true, computes sunrise time; if false, computes sunset time | ||
| * \\return The ephemeris time (ET seconds past J2000) of the solar event | ||
| * | ||
| * \\throw SpiceException If no sunrise/sunset found for the given date/location | ||
| * (e.g., polar day or night) |
There was a problem hiding this comment.
| * \\param lat_deg Latitude in degrees | |
| * \\param lon_deg Longitude in degrees | |
| * \\param utc_date UTC date as a string (e.g., "2024-01-01") | |
| * \\param observer The observing body (e.g., "EARTH") | |
| * \\param isSunrise If true, computes sunrise time; if false, computes sunset time | |
| * \\return The ephemeris time (ET seconds past J2000) of the solar event | |
| * | |
| * \\throw SpiceException If no sunrise/sunset found for the given date/location | |
| * (e.g., polar day or night) | |
| * \param latitude Latitude in degrees | |
| * \param longitude Longitude in degrees | |
| * \param date UTC date as a string (e.g., "2024-01-01") | |
| * \param observer The observing body (e.g., "EARTH") | |
| * \param isSunrise If true, computes sunrise time; if false, computes sunset time | |
| * \return The ephemeris time (ET seconds past J2000) of the solar event | |
| * | |
| * \throw SpiceException If no sunrise/sunset found for the given date/location | |
| * (e.g., polar day or night) |
| double solarEventTime(double lat_deg, double lon_deg, const std::string& utc_date, | ||
| const std::string& observer, bool isSunrise) const; |
There was a problem hiding this comment.
| double solarEventTime(double lat_deg, double lon_deg, const std::string& utc_date, | |
| const std::string& observer, bool isSunrise) const; | |
| double solarEventTime(double latitude, double longitude, const std::string& date, | |
| const std::string& observer, bool isSunrise) const; |
| std::string_view date = global::timeManager->time().ISO8601(); | ||
| std::string_view dateTrim = date.substr(0, date.find('T')); | ||
| std::string dateStr(dateTrim); | ||
| std::string globe = global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | ||
| return SpiceManager::ref().solarEventTime(lon, lat, dateStr.c_str(), globe, false); |
There was a problem hiding this comment.
| std::string_view date = global::timeManager->time().ISO8601(); | |
| std::string_view dateTrim = date.substr(0, date.find('T')); | |
| std::string dateStr(dateTrim); | |
| std::string globe = global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | |
| return SpiceManager::ref().solarEventTime(lon, lat, dateStr.c_str(), globe, false); | |
| std::string date = global::timeManager->time().ISO8601(); | |
| std::string dateTrim = date.substr(0, date.find('T')); | |
| std::string globe = global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | |
| constexpr bool IsSunrise = true; | |
| return SpiceManager::ref().solarEventTime(lon, lat, dateTrim, globe, IsSunrise); |
| std::string_view date = global::timeManager->time().ISO8601(); | ||
| std::string_view dateTrim = date.substr(0, date.find('T')); | ||
| std::string dateStr(dateTrim); | ||
| std::string globe = global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | ||
| return SpiceManager::ref().solarEventTime(lon, lat, dateStr.c_str(), globe, true); |
There was a problem hiding this comment.
| std::string_view date = global::timeManager->time().ISO8601(); | |
| std::string_view dateTrim = date.substr(0, date.find('T')); | |
| std::string dateStr(dateTrim); | |
| std::string globe = global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | |
| return SpiceManager::ref().solarEventTime(lon, lat, dateStr.c_str(), globe, true); | |
| std::string date = global::timeManager->time().ISO8601(); | |
| std::string dateTrim = date.substr(0, date.find('T')); | |
| std::string globe = global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | |
| constexpr bool IsSunrise = false; | |
| return SpiceManager::ref().solarEventTime(lon, lat, dateTrim, globe, IsSunrise); |
| return res; | ||
| } | ||
|
|
||
| [[codegen::luawrap]] double sunriseTimeForSimulation() { |
There was a problem hiding this comment.
The functions would become more useful if they'd have an optional parameter that is the date, and only if the parameter is not specified we'd use the current simulation time. Ofc the ForSimulation would be removed from the function name
|
|
||
| if (!found) { | ||
| std::string eventType = isSunrise ? "sunrise" : "sunset"; | ||
| throwSpiceError("No " + eventType + " found for the given date/location"); |
There was a problem hiding this comment.
| throwSpiceError("No " + eventType + " found for the given date/location"); | |
| throwSpiceError(std::format( | |
| "No {} found for the given date/location", | |
| eventType | |
| )); |
| } | ||
|
|
||
| if (!found) { | ||
| std::string eventType = isSunrise ? "sunrise" : "sunset"; |
There was a problem hiding this comment.
| std::string eventType = isSunrise ? "sunrise" : "sunset"; | |
| const std::string_view eventType = isSunrise ? "sunrise" : "sunset"; |
| while (b - a > tol) { | ||
| double mid = 0.5 * (a + b); | ||
| double fm = solarElevation(mid); | ||
| if (isSunrise ? (fm < 0.0) : (fm >= 0.0)) a = mid; else b = mid; |
There was a problem hiding this comment.
| if (isSunrise ? (fm < 0.0) : (fm >= 0.0)) a = mid; else b = mid; | |
| if (isSunrise ? (fm < 0.0) : (fm >= 0.0)) { | |
| a = mid; | |
| } | |
| else { | |
| b = mid; | |
| } |
| /** | ||
| * Helper function to compute solar event times (sunrise/sunset). | ||
| * Both sunriseTime and sunsetTime delegate to SpiceManager::solarEventTime. | ||
| */ |
There was a problem hiding this comment.
This will currently become the documentation for the sunriseTime function
| [[codegen::luawrap]] double sunriseTime(double lat_deg, double lon_deg, | ||
| std::string utc_date, std::string observer) { | ||
| return SpiceManager::ref().solarEventTime(lat_deg, lon_deg, utc_date, observer, true); | ||
| } | ||
|
|
||
| [[codegen::luawrap]] double sunsetTime(double lat_deg, double lon_deg, | ||
| std::string utc_date, std::string observer) { | ||
| return SpiceManager::ref().solarEventTime(lat_deg, lon_deg, utc_date, observer, false); | ||
| } |
There was a problem hiding this comment.
These functions should get their own proper documentation
| /** | ||
| * Computes the time of a solar event (sunrise or sunset) for a given location | ||
| * and date using bisection search on the solar elevation angle. | ||
| * | ||
| * \\param latitude The latitude in degrees (range: -90 to 90) | ||
| * \\param longitude The longitude in degrees (range: -180 to 180) | ||
| * \\param altitude The observer's altitude above the surface in meters | ||
| * (default: 0.0 for sea level) | ||
| * \\param date UTC date as a string (e.g., "2024-01-01") | ||
| * \\param observer The SPICE name of the observing body (e.g., "EARTH") | ||
| * \\param isSunrise If \\p true, computes sunrise; if \\p false, computes sunset | ||
| * \\return The ephemeris time (ET seconds past J2000) of the requested solar | ||
| * event | ||
| * | ||
| * \\throw SpiceException If no sunrise/sunset is found for the given | ||
| * date/location (e.g., polar day or night) | ||
| * \\throw SpiceException If required SPICE kernels are not loaded or if the | ||
| * observer is not a valid SPICE object | ||
| * \\pre \\p latitude must be between -90 and 90 | ||
| * \\pre \\p longitude must be between -180 and 180 | ||
| * \\pre \\p date must be a valid UTC date string | ||
| * \\pre \\p observer must be a valid SPICE body name | ||
| */ | ||
| double solarEventTime(double latitude, double longitude, double altitude, | ||
| const std::string& date, const std::string& observer, | ||
| bool isSunrise) const; |
There was a problem hiding this comment.
| /** | |
| * Computes the time of a solar event (sunrise or sunset) for a given location | |
| * and date using bisection search on the solar elevation angle. | |
| * | |
| * \\param latitude The latitude in degrees (range: -90 to 90) | |
| * \\param longitude The longitude in degrees (range: -180 to 180) | |
| * \\param altitude The observer's altitude above the surface in meters | |
| * (default: 0.0 for sea level) | |
| * \\param date UTC date as a string (e.g., "2024-01-01") | |
| * \\param observer The SPICE name of the observing body (e.g., "EARTH") | |
| * \\param isSunrise If \\p true, computes sunrise; if \\p false, computes sunset | |
| * \\return The ephemeris time (ET seconds past J2000) of the requested solar | |
| * event | |
| * | |
| * \\throw SpiceException If no sunrise/sunset is found for the given | |
| * date/location (e.g., polar day or night) | |
| * \\throw SpiceException If required SPICE kernels are not loaded or if the | |
| * observer is not a valid SPICE object | |
| * \\pre \\p latitude must be between -90 and 90 | |
| * \\pre \\p longitude must be between -180 and 180 | |
| * \\pre \\p date must be a valid UTC date string | |
| * \\pre \\p observer must be a valid SPICE body name | |
| */ | |
| double solarEventTime(double latitude, double longitude, double altitude, | |
| const std::string& date, const std::string& observer, | |
| bool isSunrise) const; | |
| /** | |
| * Computes the time of a solar event (sunrise or sunset) for a given location and | |
| * date using bisection search on the solar elevation angle. | |
| * | |
| * \param latitude The latitude in degrees (range: -90 to 90) | |
| * \param longitude The longitude in degrees (range: -180 to 180) | |
| * \param altitude The observer's altitude above the surface in meters (default: 0.0 | |
| for sea level) | |
| * \param date UTC date as a string (e.g., "2024-01-01") | |
| * \param observer The SPICE name of the observing body (e.g., "EARTH") | |
| * \param isSunrise If \\p true, computes sunrise; if \\p false, computes sunset | |
| * \return The ephemeris time (ET seconds past J2000) of the requested solar event | |
| * | |
| * \throw SpiceException If no sunrise/sunset is found for the given date/location | |
| * (e.g., polar day or night) | |
| * \throw SpiceException If required SPICE kernels are not loaded or if the observer | |
| * is not a valid SPICE object | |
| * \pre \p latitude must be between -90 and 90 | |
| * \pre \p longitude must be between -180 and 180 | |
| * \pre \p date must be a valid UTC date string | |
| * \pre \p observer must be a valid SPICE body name | |
| */ | |
| double solarEventTime(double latitude, double longitude, double altitude, | |
| const std::string& date, const std::string& observer, bool isSunrise) const; |
| #include <openspace/util/timemanager.h> | ||
| #include <openspace/util/spicemanager.h> |
There was a problem hiding this comment.
| #include <openspace/util/timemanager.h> | |
| #include <openspace/util/spicemanager.h> | |
| #include <openspace/util/spicemanager.h> | |
| #include <openspace/util/timemanager.h> |
| * Return the ephemeris time (ET seconds past J2000) of sunrise for the current | ||
| * camera position |
There was a problem hiding this comment.
| * Return the ephemeris time (ET seconds past J2000) of sunrise for the current | |
| * camera position | |
| * Return the ephemeris time (ET seconds past J2000) of sunrise for the current camera | |
| * position. |
| [[codegen::luawrap]] double sunriseTime(bool useCameraAltitude = true, | ||
| std::string date = "") { | ||
| auto [lat, lon, alt] = geoPositionForCamera(); | ||
| if (date.empty()) { | ||
| date = global::timeManager->time().ISO8601(); | ||
| } | ||
| std::string dateTrim = date.substr(0, date.find('T')); | ||
| std::string globe = global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | ||
| double eventAlt = useCameraAltitude ? alt : 0.0; | ||
| constexpr bool IsSunrise = true; | ||
| return SpiceManager::ref().solarEventTime(lat, lon, eventAlt, dateTrim, globe, IsSunrise); |
There was a problem hiding this comment.
| [[codegen::luawrap]] double sunriseTime(bool useCameraAltitude = true, | |
| std::string date = "") { | |
| auto [lat, lon, alt] = geoPositionForCamera(); | |
| if (date.empty()) { | |
| date = global::timeManager->time().ISO8601(); | |
| } | |
| std::string dateTrim = date.substr(0, date.find('T')); | |
| std::string globe = global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | |
| double eventAlt = useCameraAltitude ? alt : 0.0; | |
| constexpr bool IsSunrise = true; | |
| return SpiceManager::ref().solarEventTime(lat, lon, eventAlt, dateTrim, globe, IsSunrise); | |
| [[codegen::luawrap]] double sunriseTime(bool useCameraAltitude = true, | |
| std::string date = "") | |
| { | |
| auto [lat, lon, alt] = geoPositionForCamera(); | |
| if (date.empty()) { | |
| date = global::timeManager->time().ISO8601(); | |
| } | |
| std::string dateTrim = date.substr(0, date.find('T')); | |
| std::string globe = | |
| global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | |
| alt = useCameraAltitude ? alt : 0.0; | |
| constexpr bool IsSunrise = true; | |
| return SpiceManager::ref().solarEventTime(lat, lon, alt, dateTrim, globe, IsSunrise); |
| [[codegen::luawrap]] double sunsetTime(bool useCameraAltitude = true, | ||
| std::string date = "") { | ||
| auto [lat, lon, alt] = geoPositionForCamera(); | ||
| if (date.empty()) { | ||
| date = global::timeManager->time().ISO8601(); | ||
| } | ||
| std::string dateTrim = date.substr(0, date.find('T')); | ||
| std::string globe = global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | ||
| double eventAlt = useCameraAltitude ? alt : 0.0; | ||
| constexpr bool IsSunrise = false; | ||
| return SpiceManager::ref().solarEventTime(lat, lon, eventAlt, dateTrim, globe, IsSunrise); |
There was a problem hiding this comment.
| [[codegen::luawrap]] double sunsetTime(bool useCameraAltitude = true, | |
| std::string date = "") { | |
| auto [lat, lon, alt] = geoPositionForCamera(); | |
| if (date.empty()) { | |
| date = global::timeManager->time().ISO8601(); | |
| } | |
| std::string dateTrim = date.substr(0, date.find('T')); | |
| std::string globe = global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | |
| double eventAlt = useCameraAltitude ? alt : 0.0; | |
| constexpr bool IsSunrise = false; | |
| return SpiceManager::ref().solarEventTime(lat, lon, eventAlt, dateTrim, globe, IsSunrise); | |
| [[codegen::luawrap]] double sunsetTime(bool useCameraAltitude = true, | |
| std::string date = "") | |
| { | |
| auto [lat, lon, alt] = geoPositionForCamera(); | |
| if (date.empty()) { | |
| date = global::timeManager->time().ISO8601(); | |
| } | |
| std::string dateTrim = date.substr(0, date.find('T')); | |
| std::string globe = | |
| global::navigationHandler->orbitalNavigator().anchorNode()->identifier(); | |
| alt = useCameraAltitude ? alt : 0.0; | |
| constexpr bool IsSunrise = false; | |
| return SpiceManager::ref().solarEventTime(lat, lon, alt, dateTrim, globe, IsSunrise); |
| georec_c(lon, lat, altitudeKm, | ||
| equatorialRadius, flattening, observerPosition); |
There was a problem hiding this comment.
| georec_c(lon, lat, altitudeKm, | |
| equatorialRadius, flattening, observerPosition); | |
| georec_c( | |
| lon, | |
| lat, | |
| altitudeKm, | |
| equatorialRadius, | |
| flattening, | |
| observerPosition | |
| ); |
| }; | ||
|
|
||
| // 3. Bisection search to find the solar event time | ||
| const double tolerance = 1.0; // seconds |
There was a problem hiding this comment.
| const double tolerance = 1.0; // seconds | |
| constexpr double Tolerance = 1.0; // seconds |
| } | ||
|
|
||
| // Refine the bracket using bisection search | ||
| while (bracketsHigh - bracketsLow > tolerance) { |
There was a problem hiding this comment.
| while (bracketsHigh - bracketsLow > tolerance) { | |
| while (bracketsHigh - bracketsLow > Tolerance) { |
| (elevationAtMidpoint >= -horizonDipAngle); | ||
| if (shouldUpdateLow) { | ||
| bracketsLow = midpoint; | ||
| } else { |
There was a problem hiding this comment.
| } else { | |
| } | |
| else { |
| return 0.5 * (bracketsLow + bracketsHigh); // ET seconds past J2000 | ||
| } | ||
|
|
||
|
|

These are the functions for getting the sunset/rise times. In separate PR I will add elements to the Night Sky panel that will let users see sunrise/set without having to script.
2026-08-18.18-46-12.mp4