]> git.earman.xyz Git - sensor-watch.git/commitdiff
bring mars time into Second Movement
authorJoey Castillo <joeycastillo@utexas.edu>
Tue, 27 May 2025 23:30:54 +0000 (19:30 -0400)
committerJoey Castillo <joeycastillo@utexas.edu>
Tue, 27 May 2025 23:30:54 +0000 (19:30 -0400)
legacy/watch_faces/clock/mars_time_face.c [deleted file]
legacy/watch_faces/clock/mars_time_face.h [deleted file]
movement_faces.h
watch-faces.mk
watch-faces/clock/mars_time_face.c [new file with mode: 0644]
watch-faces/clock/mars_time_face.h [new file with mode: 0644]

diff --git a/legacy/watch_faces/clock/mars_time_face.c b/legacy/watch_faces/clock/mars_time_face.c
deleted file mode 100644 (file)
index 5c55cd1..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2022 Joey Castillo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include "watch_utility.h"
-#include "mars_time_face.h"
-
-// note: lander coordinates come from Mars24's `marslandmarks.xml` file
-static double site_longitudes[MARS_TIME_NUM_SITES] = {
-    0,                      // Mars Coordinated Time, at the meridian
-    360.0 - 109.9,          // Zhurong lander site
-    360.0 - 77.45088572,    // Perseverance lander site
-    360.0 - 135.623447,     // InSight lander site
-    360.0 - 137.441635,     // Curiosity lander site
-};
-
-static char site_names[MARS_TIME_NUM_SITES][3] = {
-    "MC",
-    "ZH",
-    "PE",
-    "IN",
-    "CU",
-};
-
-static uint16_t landing_sols[MARS_TIME_NUM_SITES] = {
-    0,
-    52387,
-    52304,
-    51511,
-    49269,
-};
-
-typedef struct {
-    uint8_t hour;
-    uint8_t minute;
-    uint8_t second;
-} mars_clock_hms_t;
-
-static void _h_to_hms(mars_clock_hms_t *date_time, double h) {
-       unsigned int seconds = (unsigned int)(h * 3600.0);
-       date_time->hour = seconds / 3600;
-       seconds = seconds % 3600;
-       date_time->minute = floor(seconds / 60);
-       date_time->second = round(seconds % 60);
-}
-
-static void _update(mars_time_state_t *state) {
-    char buf[11];
-    watch_date_time_t date_time = watch_rtc_get_date_time();
-    uint32_t now = watch_utility_date_time_to_unix_time(date_time, movement_get_current_timezone_offset());
-    // TODO: I'm skipping over some steps here.
-    // https://www.giss.nasa.gov/tools/mars24/help/algorithm.html
-    double jdut = 2440587.5 + ((double)now / 86400.0);
-    double jdtt = jdut + ((37.0 + 32.184) / 86400.0);
-    double jd2k = jdtt - 2451545.0;
-    double msd = ((jd2k - 4.5) / 1.0274912517) + 44796.0 - 0.0009626;
-    double mtc = fmod(24 * msd, 24);
-    double lmt;
-
-    if (state->current_site == 0) {
-        lmt = mtc;
-    } else {
-        double longitude = site_longitudes[state->current_site];
-        double lmst = mtc - ((longitude * 24.0) / 360.0);
-        lmt = fmod(lmst + 24, 24);
-    }
-
-    if (state->displaying_sol) {
-        // TODO: this is not right, mission sol should turn over at midnight local time?
-        uint16_t sol = floor(msd) - landing_sols[state->current_site];
-        if (sol < 1000) sprintf(&buf[0], "%s  Sol%3d", site_names[state->current_site], sol);
-        else sprintf(&buf[0], "%s $%6d", site_names[state->current_site], sol);
-        watch_clear_colon();
-        watch_clear_indicator(WATCH_INDICATOR_24H);
-    } else {
-        mars_clock_hms_t mars_time;
-        _h_to_hms(&mars_time, lmt);
-        sprintf(&buf[0], "%s  %02d%02d%02d", site_names[state->current_site], mars_time.hour, mars_time.minute, mars_time.second);
-        watch_set_colon();
-        watch_set_indicator(WATCH_INDICATOR_24H);
-    }
-
-    watch_display_string(buf, 0);
-}
-
-void mars_time_face_setup(uint8_t watch_face_index, void ** context_ptr) {
-    (void) watch_face_index;
-    if (*context_ptr == NULL) {
-        *context_ptr = malloc(sizeof(mars_time_state_t));
-        memset(*context_ptr, 0, sizeof(mars_time_state_t));
-    }
-}
-
-void mars_time_face_activate(void *context) {
-    mars_time_state_t *state = (mars_time_state_t *)context;
-    (void) state;
-}
-
-bool mars_time_face_loop(movement_event_t event, void *context) {
-    mars_time_state_t *state = (mars_time_state_t *)context;
-
-    switch (event.event_type) {
-        case EVENT_ACTIVATE:
-        case EVENT_TICK:
-            _update(state);
-            break;
-        case EVENT_LIGHT_BUTTON_UP:
-            state->displaying_sol = !state->displaying_sol;
-            _update(state);
-            break;
-        case EVENT_LIGHT_LONG_PRESS:
-            movement_illuminate_led();
-            break;
-        case EVENT_ALARM_BUTTON_UP:
-            state->current_site = (state->current_site + 1) % MARS_TIME_NUM_SITES;
-            _update(state);
-            break;
-        case EVENT_TIMEOUT:
-            // TODO: make this lower power so we can avoid timeout
-            movement_move_to_face(0);
-            break;
-        case EVENT_LOW_ENERGY_UPDATE:
-            // TODO: low energy update
-            // watch_start_sleep_animation(500);
-            break;
-        case EVENT_LIGHT_BUTTON_DOWN:
-            // don't light up every time light is hit
-            break;
-        default:
-            movement_default_loop_handler(event);
-            break;
-    }
-
-    return true;
-}
-
-void mars_time_face_resign(void *context) {
-    (void) context;
-}
-
diff --git a/legacy/watch_faces/clock/mars_time_face.h b/legacy/watch_faces/clock/mars_time_face.h
deleted file mode 100644 (file)
index ddb43e6..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2022 Joey Castillo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef MARS_TIME_FACE_H_
-#define MARS_TIME_FACE_H_
-
-/*
- * MARS TIME face
- *
- * This watch face is dedicated to Martian timekeeping.
- * It has several modes, and can display either a time or a date.
- *
- * Pressing the ALARM button cycles through different time zones on Mars:
- *   MC - Mars Coordinated Time, the time at Airy-0 Crater on the Martian prime meridian
- *   ZH - Local mean solar time for the Zhurong rover
- *   PE - LMST for the Perseverance rover
- *   IN - LMST for the Insight lander
- *   CU - LMST for the Curiosity rover
- *
- * Press the LIGHT button to toggle between displaying time and date:
- *   MC S - the Mars Sol Date, Martian days since December 29, 1873
- *   ZH Sol - Mission sol for the Zhurong rover
- *   PE Sol - Mission sol for the Perseverance rover
- *   IN S - Mission sol for the InSight lander
- *   CU S - Mission sol for the Curiosity rover
- *
- * Note that where the mission sol is below 1000, this watch face displays
- * the word “Sol” on the bottom line. When the mission sol is over 1000, the
- * word “Sol” will not fit and so it displays a stylized letter S at the top
- * right.
- */
-
-#include "movement.h"
-
-typedef enum {
-    MARS_TIME_MERIDIAN,
-    MARS_TIME_ZHURONG_SITE,
-    MARS_TIME_PERSEVERANCE_SITE,
-    MARS_TIME_INSIGHT_SITE,
-    MARS_TIME_CURIOSITY_SITE,
-    MARS_TIME_NUM_SITES,
-} mars_time_site_t;
-
-typedef struct {
-    mars_time_site_t current_site;
-    bool displaying_sol;
-} mars_time_state_t;
-
-void mars_time_face_setup(uint8_t watch_face_index, void ** context_ptr);
-void mars_time_face_activate(void *context);
-bool mars_time_face_loop(movement_event_t event, void *context);
-void mars_time_face_resign(void *context);
-
-#define mars_time_face ((const watch_face_t){ \
-    mars_time_face_setup, \
-    mars_time_face_activate, \
-    mars_time_face_loop, \
-    mars_time_face_resign, \
-    NULL, \
-})
-
-#endif // MARS_TIME_FACE_H_
-
index 0ac1545eacbfda27617becca9235a79b9e25ac3e..63d65bc983f3f5179a772100b632fe468ee29b1b 100644 (file)
@@ -50,4 +50,5 @@
 #include "chirpy_demo_face.h"
 #include "finetune_face.h"
 #include "nanosec_face.h"
+#include "mars_time_face.h"
 // New includes go above this line.
index 8a9d29c89eba976211f1613f6ade0becddc6e31e..182e54fdc4cceeee64d07192ce7fbf082b0e5a20 100644 (file)
@@ -2,6 +2,7 @@ SRCS += \
   ./watch-faces/clock/clock_face.c \
   ./watch-faces/clock/beats_face.c \
   ./watch-faces/clock/world_clock_face.c \
+  ./watch-faces/clock/mars_time_face.c \
   ./watch-faces/complication/alarm_face.c \
   ./watch-faces/complication/advanced_alarm_face.c \
   ./watch-faces/complication/countdown_face.c \
diff --git a/watch-faces/clock/mars_time_face.c b/watch-faces/clock/mars_time_face.c
new file mode 100644 (file)
index 0000000..2d06826
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Joey Castillo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "watch_utility.h"
+#include "mars_time_face.h"
+
+// note: lander coordinates come from Mars24's `marslandmarks.xml` file
+static double site_longitudes[MARS_TIME_NUM_SITES] = {
+    0,                      // Mars Coordinated Time, at the meridian
+    360.0 - 77.45088572,    // Perseverance lander site
+    360.0 - 137.441635,     // Curiosity lander site
+};
+
+static char site_names_classic[MARS_TIME_NUM_SITES][3] = {
+    "MC",
+    "PE",
+    "CU",
+};
+
+static char site_names_custom[MARS_TIME_NUM_SITES][4] = {
+    "MTC",
+    "PER",
+    "CUR",
+};
+
+static uint16_t landing_sols[MARS_TIME_NUM_SITES] = {
+    0,
+    52304,
+    49269,
+};
+
+typedef struct {
+    uint8_t hour;
+    uint8_t minute;
+    uint8_t second;
+} mars_clock_hms_t;
+
+static void _h_to_hms(mars_clock_hms_t *date_time, double h) {
+       unsigned int seconds = (unsigned int)(h * 3600.0);
+       date_time->hour = seconds / 3600;
+       seconds = seconds % 3600;
+       date_time->minute = floor(seconds / 60);
+       date_time->second = round(seconds % 60);
+}
+
+static void _update(mars_time_state_t *state) {
+    char buf[8];
+    watch_date_time_t date_time = movement_get_local_date_time();
+    uint32_t now = watch_utility_date_time_to_unix_time(date_time, movement_get_current_timezone_offset());
+    // TODO: I'm skipping over some steps here.
+    // https://www.giss.nasa.gov/tools/mars24/help/algorithm.html
+    double jdut = 2440587.5 + ((double)now / 86400.0);
+    double jdtt = jdut + ((37.0 + 32.184) / 86400.0);
+    double jd2k = jdtt - 2451545.0;
+    double msd = ((jd2k - 4.5) / 1.0274912517) + 44796.0 - 0.0009626;
+    double mtc = fmod(24 * msd, 24);
+    double lmt;
+
+    if (state->current_site == 0) {
+        lmt = mtc;
+    } else {
+        double longitude = site_longitudes[state->current_site];
+        double lmst = mtc - ((longitude * 24.0) / 360.0);
+        lmt = fmod(lmst + 24, 24);
+    }
+
+    watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, site_names_custom[state->current_site], site_names_classic[state->current_site]);
+
+    if (state->displaying_sol) {
+        // TODO: this is not right, mission sol should turn over at midnight local time?
+        uint16_t sol = floor(msd) - landing_sols[state->current_site];
+        sprintf(buf, "%6d", sol);
+        watch_display_text(WATCH_POSITION_TOP_RIGHT, " $");
+        watch_display_text(WATCH_POSITION_BOTTOM, buf);
+        watch_clear_colon();
+        watch_clear_indicator(WATCH_INDICATOR_24H);
+    } else {
+        mars_clock_hms_t mars_time;
+        _h_to_hms(&mars_time, lmt);
+        sprintf(buf, "%02d%02d%02d", mars_time.hour, mars_time.minute, mars_time.second);
+        watch_display_text(WATCH_POSITION_TOP_RIGHT, "  ");
+        watch_display_text(WATCH_POSITION_BOTTOM, buf);
+        watch_set_colon();
+        watch_set_indicator(WATCH_INDICATOR_24H);
+    }
+}
+
+void mars_time_face_setup(uint8_t watch_face_index, void ** context_ptr) {
+    (void) watch_face_index;
+    if (*context_ptr == NULL) {
+        *context_ptr = malloc(sizeof(mars_time_state_t));
+        memset(*context_ptr, 0, sizeof(mars_time_state_t));
+    }
+}
+
+void mars_time_face_activate(void *context) {
+    mars_time_state_t *state = (mars_time_state_t *)context;
+    (void) state;
+}
+
+bool mars_time_face_loop(movement_event_t event, void *context) {
+    mars_time_state_t *state = (mars_time_state_t *)context;
+
+    switch (event.event_type) {
+        case EVENT_ACTIVATE:
+        case EVENT_TICK:
+            _update(state);
+            break;
+        case EVENT_LIGHT_BUTTON_UP:
+            state->displaying_sol = !state->displaying_sol;
+            _update(state);
+            break;
+        case EVENT_LIGHT_LONG_PRESS:
+            movement_illuminate_led();
+            break;
+        case EVENT_ALARM_BUTTON_UP:
+            state->current_site = (state->current_site + 1) % MARS_TIME_NUM_SITES;
+            _update(state);
+            break;
+        case EVENT_TIMEOUT:
+            // TODO: make this lower power so we can avoid timeout
+            movement_move_to_face(0);
+            break;
+        case EVENT_LOW_ENERGY_UPDATE:
+            // TODO: low energy update
+            // watch_start_sleep_animation(500);
+            break;
+        case EVENT_LIGHT_BUTTON_DOWN:
+            // don't light up every time light is hit
+            break;
+        default:
+            movement_default_loop_handler(event);
+            break;
+    }
+
+    return true;
+}
+
+void mars_time_face_resign(void *context) {
+    (void) context;
+}
+
diff --git a/watch-faces/clock/mars_time_face.h b/watch-faces/clock/mars_time_face.h
new file mode 100644 (file)
index 0000000..8895c05
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Joey Castillo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef MARS_TIME_FACE_H_
+#define MARS_TIME_FACE_H_
+
+/*
+ * MARS TIME face
+ *
+ * This watch face is dedicated to Martian timekeeping.
+ * It has several modes, and can display either a time or a date.
+ *
+ * Pressing the ALARM button cycles through different time zones on Mars:
+ *   MC - Mars Coordinated Time, the time at Airy-0 Crater on the Martian prime meridian
+ *   ZH - Local mean solar time for the Zhurong rover
+ *   PE - LMST for the Perseverance rover
+ *   IN - LMST for the Insight lander
+ *   CU - LMST for the Curiosity rover
+ *
+ * Press the LIGHT button to toggle between displaying time and date:
+ *   MC S - the Mars Sol Date, Martian days since December 29, 1873
+ *   ZH Sol - Mission sol for the Zhurong rover
+ *   PE Sol - Mission sol for the Perseverance rover
+ *   IN S - Mission sol for the InSight lander
+ *   CU S - Mission sol for the Curiosity rover
+ *
+ * Note that where the mission sol is below 1000, this watch face displays
+ * the word “Sol” on the bottom line. When the mission sol is over 1000, the
+ * word “Sol” will not fit and so it displays a stylized letter S at the top
+ * right.
+ */
+
+#include "movement.h"
+
+typedef enum {
+    MARS_TIME_MERIDIAN,
+    MARS_TIME_PERSEVERANCE_SITE,
+    MARS_TIME_CURIOSITY_SITE,
+    MARS_TIME_NUM_SITES,
+} mars_time_site_t;
+
+typedef struct {
+    mars_time_site_t current_site;
+    bool displaying_sol;
+} mars_time_state_t;
+
+void mars_time_face_setup(uint8_t watch_face_index, void ** context_ptr);
+void mars_time_face_activate(void *context);
+bool mars_time_face_loop(movement_event_t event, void *context);
+void mars_time_face_resign(void *context);
+
+#define mars_time_face ((const watch_face_t){ \
+    mars_time_face_setup, \
+    mars_time_face_activate, \
+    mars_time_face_loop, \
+    mars_time_face_resign, \
+    NULL, \
+})
+
+#endif // MARS_TIME_FACE_H_
+