Compare commits

...

3 Commits

Author SHA1 Message Date
firestarsdog 422488562f SLC Alert QoL 2026-09-06 02:04:33 -04:00
Prabhaav Pillai 7f1f926c47 build - first from me 2026-09-06 01:58:30 -04:00
Prabhaav Pillai 9cb1b6b11d big dipper 2026-09-06 01:35:01 -04:00
108 changed files with 1944 additions and 1404 deletions
Binary file not shown.
+1
View File
@@ -310,6 +310,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"DeveloperSidebarMetric7", {PERSISTENT, INT, "7", "0", 3}},
{"DeveloperUI", {PERSISTENT, BOOL, "0", "0", 3}},
{"GalaxyDeveloperMode", {PERSISTENT | DONT_LOG, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
{"GalaxyMobileDefault", {PERSISTENT | DONT_LOG, BOOL, "0", "0", 0, SETTINGS_ADVANCED}},
{"DeveloperWidgets", {PERSISTENT, BOOL, "1", "0", 3}},
{"DeviceManagement", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
{"DeviceShutdown", {PERSISTENT, INT, "6", "6", 1, SETTINGS_SIMPLE}},
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1,2 +1,2 @@
extern const uint8_t gitversion[19];
const uint8_t gitversion[19] = "DEV-cec1a0fb-DEBUG";
const uint8_t gitversion[19] = "DEV-9cb1b6b1-DEBUG";
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
DEV-cec1a0fb-DEBUG
DEV-9cb1b6b1-DEBUG
Binary file not shown.
+342 -342
View File
@@ -45,326 +45,326 @@ const static double MAHA_THRESH_31 = 3.8414588206941227;
* *
* This file is part of 'ekf' *
******************************************************************************/
void err_fun(double *nom_x, double *delta_x, double *out_5825026556611430403) {
out_5825026556611430403[0] = delta_x[0] + nom_x[0];
out_5825026556611430403[1] = delta_x[1] + nom_x[1];
out_5825026556611430403[2] = delta_x[2] + nom_x[2];
out_5825026556611430403[3] = delta_x[3] + nom_x[3];
out_5825026556611430403[4] = delta_x[4] + nom_x[4];
out_5825026556611430403[5] = delta_x[5] + nom_x[5];
out_5825026556611430403[6] = delta_x[6] + nom_x[6];
out_5825026556611430403[7] = delta_x[7] + nom_x[7];
out_5825026556611430403[8] = delta_x[8] + nom_x[8];
void err_fun(double *nom_x, double *delta_x, double *out_694062864366320957) {
out_694062864366320957[0] = delta_x[0] + nom_x[0];
out_694062864366320957[1] = delta_x[1] + nom_x[1];
out_694062864366320957[2] = delta_x[2] + nom_x[2];
out_694062864366320957[3] = delta_x[3] + nom_x[3];
out_694062864366320957[4] = delta_x[4] + nom_x[4];
out_694062864366320957[5] = delta_x[5] + nom_x[5];
out_694062864366320957[6] = delta_x[6] + nom_x[6];
out_694062864366320957[7] = delta_x[7] + nom_x[7];
out_694062864366320957[8] = delta_x[8] + nom_x[8];
}
void inv_err_fun(double *nom_x, double *true_x, double *out_8876036798993240698) {
out_8876036798993240698[0] = -nom_x[0] + true_x[0];
out_8876036798993240698[1] = -nom_x[1] + true_x[1];
out_8876036798993240698[2] = -nom_x[2] + true_x[2];
out_8876036798993240698[3] = -nom_x[3] + true_x[3];
out_8876036798993240698[4] = -nom_x[4] + true_x[4];
out_8876036798993240698[5] = -nom_x[5] + true_x[5];
out_8876036798993240698[6] = -nom_x[6] + true_x[6];
out_8876036798993240698[7] = -nom_x[7] + true_x[7];
out_8876036798993240698[8] = -nom_x[8] + true_x[8];
void inv_err_fun(double *nom_x, double *true_x, double *out_7656216431051591408) {
out_7656216431051591408[0] = -nom_x[0] + true_x[0];
out_7656216431051591408[1] = -nom_x[1] + true_x[1];
out_7656216431051591408[2] = -nom_x[2] + true_x[2];
out_7656216431051591408[3] = -nom_x[3] + true_x[3];
out_7656216431051591408[4] = -nom_x[4] + true_x[4];
out_7656216431051591408[5] = -nom_x[5] + true_x[5];
out_7656216431051591408[6] = -nom_x[6] + true_x[6];
out_7656216431051591408[7] = -nom_x[7] + true_x[7];
out_7656216431051591408[8] = -nom_x[8] + true_x[8];
}
void H_mod_fun(double *state, double *out_6203949078932441352) {
out_6203949078932441352[0] = 1.0;
out_6203949078932441352[1] = 0.0;
out_6203949078932441352[2] = 0.0;
out_6203949078932441352[3] = 0.0;
out_6203949078932441352[4] = 0.0;
out_6203949078932441352[5] = 0.0;
out_6203949078932441352[6] = 0.0;
out_6203949078932441352[7] = 0.0;
out_6203949078932441352[8] = 0.0;
out_6203949078932441352[9] = 0.0;
out_6203949078932441352[10] = 1.0;
out_6203949078932441352[11] = 0.0;
out_6203949078932441352[12] = 0.0;
out_6203949078932441352[13] = 0.0;
out_6203949078932441352[14] = 0.0;
out_6203949078932441352[15] = 0.0;
out_6203949078932441352[16] = 0.0;
out_6203949078932441352[17] = 0.0;
out_6203949078932441352[18] = 0.0;
out_6203949078932441352[19] = 0.0;
out_6203949078932441352[20] = 1.0;
out_6203949078932441352[21] = 0.0;
out_6203949078932441352[22] = 0.0;
out_6203949078932441352[23] = 0.0;
out_6203949078932441352[24] = 0.0;
out_6203949078932441352[25] = 0.0;
out_6203949078932441352[26] = 0.0;
out_6203949078932441352[27] = 0.0;
out_6203949078932441352[28] = 0.0;
out_6203949078932441352[29] = 0.0;
out_6203949078932441352[30] = 1.0;
out_6203949078932441352[31] = 0.0;
out_6203949078932441352[32] = 0.0;
out_6203949078932441352[33] = 0.0;
out_6203949078932441352[34] = 0.0;
out_6203949078932441352[35] = 0.0;
out_6203949078932441352[36] = 0.0;
out_6203949078932441352[37] = 0.0;
out_6203949078932441352[38] = 0.0;
out_6203949078932441352[39] = 0.0;
out_6203949078932441352[40] = 1.0;
out_6203949078932441352[41] = 0.0;
out_6203949078932441352[42] = 0.0;
out_6203949078932441352[43] = 0.0;
out_6203949078932441352[44] = 0.0;
out_6203949078932441352[45] = 0.0;
out_6203949078932441352[46] = 0.0;
out_6203949078932441352[47] = 0.0;
out_6203949078932441352[48] = 0.0;
out_6203949078932441352[49] = 0.0;
out_6203949078932441352[50] = 1.0;
out_6203949078932441352[51] = 0.0;
out_6203949078932441352[52] = 0.0;
out_6203949078932441352[53] = 0.0;
out_6203949078932441352[54] = 0.0;
out_6203949078932441352[55] = 0.0;
out_6203949078932441352[56] = 0.0;
out_6203949078932441352[57] = 0.0;
out_6203949078932441352[58] = 0.0;
out_6203949078932441352[59] = 0.0;
out_6203949078932441352[60] = 1.0;
out_6203949078932441352[61] = 0.0;
out_6203949078932441352[62] = 0.0;
out_6203949078932441352[63] = 0.0;
out_6203949078932441352[64] = 0.0;
out_6203949078932441352[65] = 0.0;
out_6203949078932441352[66] = 0.0;
out_6203949078932441352[67] = 0.0;
out_6203949078932441352[68] = 0.0;
out_6203949078932441352[69] = 0.0;
out_6203949078932441352[70] = 1.0;
out_6203949078932441352[71] = 0.0;
out_6203949078932441352[72] = 0.0;
out_6203949078932441352[73] = 0.0;
out_6203949078932441352[74] = 0.0;
out_6203949078932441352[75] = 0.0;
out_6203949078932441352[76] = 0.0;
out_6203949078932441352[77] = 0.0;
out_6203949078932441352[78] = 0.0;
out_6203949078932441352[79] = 0.0;
out_6203949078932441352[80] = 1.0;
void H_mod_fun(double *state, double *out_2454126163912067491) {
out_2454126163912067491[0] = 1.0;
out_2454126163912067491[1] = 0.0;
out_2454126163912067491[2] = 0.0;
out_2454126163912067491[3] = 0.0;
out_2454126163912067491[4] = 0.0;
out_2454126163912067491[5] = 0.0;
out_2454126163912067491[6] = 0.0;
out_2454126163912067491[7] = 0.0;
out_2454126163912067491[8] = 0.0;
out_2454126163912067491[9] = 0.0;
out_2454126163912067491[10] = 1.0;
out_2454126163912067491[11] = 0.0;
out_2454126163912067491[12] = 0.0;
out_2454126163912067491[13] = 0.0;
out_2454126163912067491[14] = 0.0;
out_2454126163912067491[15] = 0.0;
out_2454126163912067491[16] = 0.0;
out_2454126163912067491[17] = 0.0;
out_2454126163912067491[18] = 0.0;
out_2454126163912067491[19] = 0.0;
out_2454126163912067491[20] = 1.0;
out_2454126163912067491[21] = 0.0;
out_2454126163912067491[22] = 0.0;
out_2454126163912067491[23] = 0.0;
out_2454126163912067491[24] = 0.0;
out_2454126163912067491[25] = 0.0;
out_2454126163912067491[26] = 0.0;
out_2454126163912067491[27] = 0.0;
out_2454126163912067491[28] = 0.0;
out_2454126163912067491[29] = 0.0;
out_2454126163912067491[30] = 1.0;
out_2454126163912067491[31] = 0.0;
out_2454126163912067491[32] = 0.0;
out_2454126163912067491[33] = 0.0;
out_2454126163912067491[34] = 0.0;
out_2454126163912067491[35] = 0.0;
out_2454126163912067491[36] = 0.0;
out_2454126163912067491[37] = 0.0;
out_2454126163912067491[38] = 0.0;
out_2454126163912067491[39] = 0.0;
out_2454126163912067491[40] = 1.0;
out_2454126163912067491[41] = 0.0;
out_2454126163912067491[42] = 0.0;
out_2454126163912067491[43] = 0.0;
out_2454126163912067491[44] = 0.0;
out_2454126163912067491[45] = 0.0;
out_2454126163912067491[46] = 0.0;
out_2454126163912067491[47] = 0.0;
out_2454126163912067491[48] = 0.0;
out_2454126163912067491[49] = 0.0;
out_2454126163912067491[50] = 1.0;
out_2454126163912067491[51] = 0.0;
out_2454126163912067491[52] = 0.0;
out_2454126163912067491[53] = 0.0;
out_2454126163912067491[54] = 0.0;
out_2454126163912067491[55] = 0.0;
out_2454126163912067491[56] = 0.0;
out_2454126163912067491[57] = 0.0;
out_2454126163912067491[58] = 0.0;
out_2454126163912067491[59] = 0.0;
out_2454126163912067491[60] = 1.0;
out_2454126163912067491[61] = 0.0;
out_2454126163912067491[62] = 0.0;
out_2454126163912067491[63] = 0.0;
out_2454126163912067491[64] = 0.0;
out_2454126163912067491[65] = 0.0;
out_2454126163912067491[66] = 0.0;
out_2454126163912067491[67] = 0.0;
out_2454126163912067491[68] = 0.0;
out_2454126163912067491[69] = 0.0;
out_2454126163912067491[70] = 1.0;
out_2454126163912067491[71] = 0.0;
out_2454126163912067491[72] = 0.0;
out_2454126163912067491[73] = 0.0;
out_2454126163912067491[74] = 0.0;
out_2454126163912067491[75] = 0.0;
out_2454126163912067491[76] = 0.0;
out_2454126163912067491[77] = 0.0;
out_2454126163912067491[78] = 0.0;
out_2454126163912067491[79] = 0.0;
out_2454126163912067491[80] = 1.0;
}
void f_fun(double *state, double dt, double *out_343822199527135251) {
out_343822199527135251[0] = state[0];
out_343822199527135251[1] = state[1];
out_343822199527135251[2] = state[2];
out_343822199527135251[3] = state[3];
out_343822199527135251[4] = state[4];
out_343822199527135251[5] = dt*((-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]))*state[6] - 9.8100000000000005*state[8] + stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*state[1]) + (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*state[4])) + state[5];
out_343822199527135251[6] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*state[4])) + state[6];
out_343822199527135251[7] = state[7];
out_343822199527135251[8] = state[8];
void f_fun(double *state, double dt, double *out_1843607112126961388) {
out_1843607112126961388[0] = state[0];
out_1843607112126961388[1] = state[1];
out_1843607112126961388[2] = state[2];
out_1843607112126961388[3] = state[3];
out_1843607112126961388[4] = state[4];
out_1843607112126961388[5] = dt*((-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]))*state[6] - 9.8100000000000005*state[8] + stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*state[1]) + (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*state[4])) + state[5];
out_1843607112126961388[6] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*state[4])) + state[6];
out_1843607112126961388[7] = state[7];
out_1843607112126961388[8] = state[8];
}
void F_fun(double *state, double dt, double *out_7416815269748566643) {
out_7416815269748566643[0] = 1;
out_7416815269748566643[1] = 0;
out_7416815269748566643[2] = 0;
out_7416815269748566643[3] = 0;
out_7416815269748566643[4] = 0;
out_7416815269748566643[5] = 0;
out_7416815269748566643[6] = 0;
out_7416815269748566643[7] = 0;
out_7416815269748566643[8] = 0;
out_7416815269748566643[9] = 0;
out_7416815269748566643[10] = 1;
out_7416815269748566643[11] = 0;
out_7416815269748566643[12] = 0;
out_7416815269748566643[13] = 0;
out_7416815269748566643[14] = 0;
out_7416815269748566643[15] = 0;
out_7416815269748566643[16] = 0;
out_7416815269748566643[17] = 0;
out_7416815269748566643[18] = 0;
out_7416815269748566643[19] = 0;
out_7416815269748566643[20] = 1;
out_7416815269748566643[21] = 0;
out_7416815269748566643[22] = 0;
out_7416815269748566643[23] = 0;
out_7416815269748566643[24] = 0;
out_7416815269748566643[25] = 0;
out_7416815269748566643[26] = 0;
out_7416815269748566643[27] = 0;
out_7416815269748566643[28] = 0;
out_7416815269748566643[29] = 0;
out_7416815269748566643[30] = 1;
out_7416815269748566643[31] = 0;
out_7416815269748566643[32] = 0;
out_7416815269748566643[33] = 0;
out_7416815269748566643[34] = 0;
out_7416815269748566643[35] = 0;
out_7416815269748566643[36] = 0;
out_7416815269748566643[37] = 0;
out_7416815269748566643[38] = 0;
out_7416815269748566643[39] = 0;
out_7416815269748566643[40] = 1;
out_7416815269748566643[41] = 0;
out_7416815269748566643[42] = 0;
out_7416815269748566643[43] = 0;
out_7416815269748566643[44] = 0;
out_7416815269748566643[45] = dt*(stiffness_front*(-state[2] - state[3] + state[7])/(mass*state[1]) + (-stiffness_front - stiffness_rear)*state[5]/(mass*state[4]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[6]/(mass*state[4]));
out_7416815269748566643[46] = -dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*pow(state[1], 2));
out_7416815269748566643[47] = -dt*stiffness_front*state[0]/(mass*state[1]);
out_7416815269748566643[48] = -dt*stiffness_front*state[0]/(mass*state[1]);
out_7416815269748566643[49] = dt*((-1 - (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*pow(state[4], 2)))*state[6] - (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*pow(state[4], 2)));
out_7416815269748566643[50] = dt*(-stiffness_front*state[0] - stiffness_rear*state[0])/(mass*state[4]) + 1;
out_7416815269748566643[51] = dt*(-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]));
out_7416815269748566643[52] = dt*stiffness_front*state[0]/(mass*state[1]);
out_7416815269748566643[53] = -9.8100000000000005*dt;
out_7416815269748566643[54] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front - pow(center_to_rear, 2)*stiffness_rear)*state[6]/(rotational_inertia*state[4]));
out_7416815269748566643[55] = -center_to_front*dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*pow(state[1], 2));
out_7416815269748566643[56] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_7416815269748566643[57] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_7416815269748566643[58] = dt*(-(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*pow(state[4], 2)) - (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*pow(state[4], 2)));
out_7416815269748566643[59] = dt*(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(rotational_inertia*state[4]);
out_7416815269748566643[60] = dt*(-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])/(rotational_inertia*state[4]) + 1;
out_7416815269748566643[61] = center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_7416815269748566643[62] = 0;
out_7416815269748566643[63] = 0;
out_7416815269748566643[64] = 0;
out_7416815269748566643[65] = 0;
out_7416815269748566643[66] = 0;
out_7416815269748566643[67] = 0;
out_7416815269748566643[68] = 0;
out_7416815269748566643[69] = 0;
out_7416815269748566643[70] = 1;
out_7416815269748566643[71] = 0;
out_7416815269748566643[72] = 0;
out_7416815269748566643[73] = 0;
out_7416815269748566643[74] = 0;
out_7416815269748566643[75] = 0;
out_7416815269748566643[76] = 0;
out_7416815269748566643[77] = 0;
out_7416815269748566643[78] = 0;
out_7416815269748566643[79] = 0;
out_7416815269748566643[80] = 1;
void F_fun(double *state, double dt, double *out_2182262497468252920) {
out_2182262497468252920[0] = 1;
out_2182262497468252920[1] = 0;
out_2182262497468252920[2] = 0;
out_2182262497468252920[3] = 0;
out_2182262497468252920[4] = 0;
out_2182262497468252920[5] = 0;
out_2182262497468252920[6] = 0;
out_2182262497468252920[7] = 0;
out_2182262497468252920[8] = 0;
out_2182262497468252920[9] = 0;
out_2182262497468252920[10] = 1;
out_2182262497468252920[11] = 0;
out_2182262497468252920[12] = 0;
out_2182262497468252920[13] = 0;
out_2182262497468252920[14] = 0;
out_2182262497468252920[15] = 0;
out_2182262497468252920[16] = 0;
out_2182262497468252920[17] = 0;
out_2182262497468252920[18] = 0;
out_2182262497468252920[19] = 0;
out_2182262497468252920[20] = 1;
out_2182262497468252920[21] = 0;
out_2182262497468252920[22] = 0;
out_2182262497468252920[23] = 0;
out_2182262497468252920[24] = 0;
out_2182262497468252920[25] = 0;
out_2182262497468252920[26] = 0;
out_2182262497468252920[27] = 0;
out_2182262497468252920[28] = 0;
out_2182262497468252920[29] = 0;
out_2182262497468252920[30] = 1;
out_2182262497468252920[31] = 0;
out_2182262497468252920[32] = 0;
out_2182262497468252920[33] = 0;
out_2182262497468252920[34] = 0;
out_2182262497468252920[35] = 0;
out_2182262497468252920[36] = 0;
out_2182262497468252920[37] = 0;
out_2182262497468252920[38] = 0;
out_2182262497468252920[39] = 0;
out_2182262497468252920[40] = 1;
out_2182262497468252920[41] = 0;
out_2182262497468252920[42] = 0;
out_2182262497468252920[43] = 0;
out_2182262497468252920[44] = 0;
out_2182262497468252920[45] = dt*(stiffness_front*(-state[2] - state[3] + state[7])/(mass*state[1]) + (-stiffness_front - stiffness_rear)*state[5]/(mass*state[4]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[6]/(mass*state[4]));
out_2182262497468252920[46] = -dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*pow(state[1], 2));
out_2182262497468252920[47] = -dt*stiffness_front*state[0]/(mass*state[1]);
out_2182262497468252920[48] = -dt*stiffness_front*state[0]/(mass*state[1]);
out_2182262497468252920[49] = dt*((-1 - (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*pow(state[4], 2)))*state[6] - (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*pow(state[4], 2)));
out_2182262497468252920[50] = dt*(-stiffness_front*state[0] - stiffness_rear*state[0])/(mass*state[4]) + 1;
out_2182262497468252920[51] = dt*(-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]));
out_2182262497468252920[52] = dt*stiffness_front*state[0]/(mass*state[1]);
out_2182262497468252920[53] = -9.8100000000000005*dt;
out_2182262497468252920[54] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front - pow(center_to_rear, 2)*stiffness_rear)*state[6]/(rotational_inertia*state[4]));
out_2182262497468252920[55] = -center_to_front*dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*pow(state[1], 2));
out_2182262497468252920[56] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_2182262497468252920[57] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_2182262497468252920[58] = dt*(-(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*pow(state[4], 2)) - (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*pow(state[4], 2)));
out_2182262497468252920[59] = dt*(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(rotational_inertia*state[4]);
out_2182262497468252920[60] = dt*(-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])/(rotational_inertia*state[4]) + 1;
out_2182262497468252920[61] = center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_2182262497468252920[62] = 0;
out_2182262497468252920[63] = 0;
out_2182262497468252920[64] = 0;
out_2182262497468252920[65] = 0;
out_2182262497468252920[66] = 0;
out_2182262497468252920[67] = 0;
out_2182262497468252920[68] = 0;
out_2182262497468252920[69] = 0;
out_2182262497468252920[70] = 1;
out_2182262497468252920[71] = 0;
out_2182262497468252920[72] = 0;
out_2182262497468252920[73] = 0;
out_2182262497468252920[74] = 0;
out_2182262497468252920[75] = 0;
out_2182262497468252920[76] = 0;
out_2182262497468252920[77] = 0;
out_2182262497468252920[78] = 0;
out_2182262497468252920[79] = 0;
out_2182262497468252920[80] = 1;
}
void h_25(double *state, double *unused, double *out_8641933420137717402) {
out_8641933420137717402[0] = state[6];
void h_25(double *state, double *unused, double *out_4798003278786560335) {
out_4798003278786560335[0] = state[6];
}
void H_25(double *state, double *unused, double *out_7339103169592445424) {
out_7339103169592445424[0] = 0;
out_7339103169592445424[1] = 0;
out_7339103169592445424[2] = 0;
out_7339103169592445424[3] = 0;
out_7339103169592445424[4] = 0;
out_7339103169592445424[5] = 0;
out_7339103169592445424[6] = 1;
out_7339103169592445424[7] = 0;
out_7339103169592445424[8] = 0;
void H_25(double *state, double *unused, double *out_7357817989096732331) {
out_7357817989096732331[0] = 0;
out_7357817989096732331[1] = 0;
out_7357817989096732331[2] = 0;
out_7357817989096732331[3] = 0;
out_7357817989096732331[4] = 0;
out_7357817989096732331[5] = 0;
out_7357817989096732331[6] = 1;
out_7357817989096732331[7] = 0;
out_7357817989096732331[8] = 0;
}
void h_24(double *state, double *unused, double *out_5501280400540853584) {
out_5501280400540853584[0] = state[4];
out_5501280400540853584[1] = state[5];
void h_24(double *state, double *unused, double *out_6970490004472512085) {
out_6970490004472512085[0] = state[4];
out_6970490004472512085[1] = state[5];
}
void H_24(double *state, double *unused, double *out_9067966288769759493) {
out_9067966288769759493[0] = 0;
out_9067966288769759493[1] = 0;
out_9067966288769759493[2] = 0;
out_9067966288769759493[3] = 0;
out_9067966288769759493[4] = 1;
out_9067966288769759493[5] = 0;
out_9067966288769759493[6] = 0;
out_9067966288769759493[7] = 0;
out_9067966288769759493[8] = 0;
out_9067966288769759493[9] = 0;
out_9067966288769759493[10] = 0;
out_9067966288769759493[11] = 0;
out_9067966288769759493[12] = 0;
out_9067966288769759493[13] = 0;
out_9067966288769759493[14] = 1;
out_9067966288769759493[15] = 0;
out_9067966288769759493[16] = 0;
out_9067966288769759493[17] = 0;
void H_24(double *state, double *unused, double *out_1156785309245570905) {
out_1156785309245570905[0] = 0;
out_1156785309245570905[1] = 0;
out_1156785309245570905[2] = 0;
out_1156785309245570905[3] = 0;
out_1156785309245570905[4] = 1;
out_1156785309245570905[5] = 0;
out_1156785309245570905[6] = 0;
out_1156785309245570905[7] = 0;
out_1156785309245570905[8] = 0;
out_1156785309245570905[9] = 0;
out_1156785309245570905[10] = 0;
out_1156785309245570905[11] = 0;
out_1156785309245570905[12] = 0;
out_1156785309245570905[13] = 0;
out_1156785309245570905[14] = 1;
out_1156785309245570905[15] = 0;
out_1156785309245570905[16] = 0;
out_1156785309245570905[17] = 0;
}
void h_30(double *state, double *unused, double *out_5706507355292462350) {
out_5706507355292462350[0] = state[4];
void h_30(double *state, double *unused, double *out_3972351172998717479) {
out_3972351172998717479[0] = state[4];
}
void H_30(double *state, double *unused, double *out_422412828100828669) {
out_422412828100828669[0] = 0;
out_422412828100828669[1] = 0;
out_422412828100828669[2] = 0;
out_422412828100828669[3] = 0;
out_422412828100828669[4] = 1;
out_422412828100828669[5] = 0;
out_422412828100828669[6] = 0;
out_422412828100828669[7] = 0;
out_422412828100828669[8] = 0;
void H_30(double *state, double *unused, double *out_7228479041953492261) {
out_7228479041953492261[0] = 0;
out_7228479041953492261[1] = 0;
out_7228479041953492261[2] = 0;
out_7228479041953492261[3] = 0;
out_7228479041953492261[4] = 1;
out_7228479041953492261[5] = 0;
out_7228479041953492261[6] = 0;
out_7228479041953492261[7] = 0;
out_7228479041953492261[8] = 0;
}
void h_26(double *state, double *unused, double *out_8743293406736795035) {
out_8743293406736795035[0] = state[7];
void h_26(double *state, double *unused, double *out_1029322094662128166) {
out_1029322094662128166[0] = state[7];
}
void H_26(double *state, double *unused, double *out_7366137585243049968) {
out_7366137585243049968[0] = 0;
out_7366137585243049968[1] = 0;
out_7366137585243049968[2] = 0;
out_7366137585243049968[3] = 0;
out_7366137585243049968[4] = 0;
out_7366137585243049968[5] = 0;
out_7366137585243049968[6] = 0;
out_7366137585243049968[7] = 1;
out_7366137585243049968[8] = 0;
void H_26(double *state, double *unused, double *out_3616314670222676107) {
out_3616314670222676107[0] = 0;
out_3616314670222676107[1] = 0;
out_3616314670222676107[2] = 0;
out_3616314670222676107[3] = 0;
out_3616314670222676107[4] = 0;
out_3616314670222676107[5] = 0;
out_3616314670222676107[6] = 0;
out_3616314670222676107[7] = 1;
out_3616314670222676107[8] = 0;
}
void h_27(double *state, double *unused, double *out_6768024602127501529) {
out_6768024602127501529[0] = state[3];
void h_27(double *state, double *unused, double *out_9195955360068189347) {
out_9195955360068189347[0] = state[3];
}
void H_27(double *state, double *unused, double *out_2597176139901253580) {
out_2597176139901253580[0] = 0;
out_2597176139901253580[1] = 0;
out_2597176139901253580[2] = 0;
out_2597176139901253580[3] = 1;
out_2597176139901253580[4] = 0;
out_2597176139901253580[5] = 0;
out_2597176139901253580[6] = 0;
out_2597176139901253580[7] = 0;
out_2597176139901253580[8] = 0;
void H_27(double *state, double *unused, double *out_5053715730153067350) {
out_5053715730153067350[0] = 0;
out_5053715730153067350[1] = 0;
out_5053715730153067350[2] = 0;
out_5053715730153067350[3] = 1;
out_5053715730153067350[4] = 0;
out_5053715730153067350[5] = 0;
out_5053715730153067350[6] = 0;
out_5053715730153067350[7] = 0;
out_5053715730153067350[8] = 0;
}
void h_29(double *state, double *unused, double *out_5090891545105754924) {
out_5090891545105754924[0] = state[1];
void h_29(double *state, double *unused, double *out_9038768691717060202) {
out_9038768691717060202[0] = state[1];
}
void H_29(double *state, double *unused, double *out_4310538866770804613) {
out_4310538866770804613[0] = 0;
out_4310538866770804613[1] = 1;
out_4310538866770804613[2] = 0;
out_4310538866770804613[3] = 0;
out_4310538866770804613[4] = 0;
out_4310538866770804613[5] = 0;
out_4310538866770804613[6] = 0;
out_4310538866770804613[7] = 0;
out_4310538866770804613[8] = 0;
void H_29(double *state, double *unused, double *out_3340353003283516317) {
out_3340353003283516317[0] = 0;
out_3340353003283516317[1] = 1;
out_3340353003283516317[2] = 0;
out_3340353003283516317[3] = 0;
out_3340353003283516317[4] = 0;
out_3340353003283516317[5] = 0;
out_3340353003283516317[6] = 0;
out_3340353003283516317[7] = 0;
out_3340353003283516317[8] = 0;
}
void h_28(double *state, double *unused, double *out_5824514749225839094) {
out_5824514749225839094[0] = state[0];
void h_28(double *state, double *unused, double *out_4249115445980516624) {
out_4249115445980516624[0] = state[0];
}
void H_28(double *state, double *unused, double *out_9053806189869216429) {
out_9053806189869216429[0] = 1;
out_9053806189869216429[1] = 0;
out_9053806189869216429[2] = 0;
out_9053806189869216429[3] = 0;
out_9053806189869216429[4] = 0;
out_9053806189869216429[5] = 0;
out_9053806189869216429[6] = 0;
out_9053806189869216429[7] = 0;
out_9053806189869216429[8] = 0;
void H_28(double *state, double *unused, double *out_5303983274848842568) {
out_5303983274848842568[0] = 1;
out_5303983274848842568[1] = 0;
out_5303983274848842568[2] = 0;
out_5303983274848842568[3] = 0;
out_5303983274848842568[4] = 0;
out_5303983274848842568[5] = 0;
out_5303983274848842568[6] = 0;
out_5303983274848842568[7] = 0;
out_5303983274848842568[8] = 0;
}
void h_31(double *state, double *unused, double *out_8917127482422223291) {
out_8917127482422223291[0] = state[8];
void h_31(double *state, double *unused, double *out_5644913485036226869) {
out_5644913485036226869[0] = state[8];
}
void H_31(double *state, double *unused, double *out_7308457207715484996) {
out_7308457207715484996[0] = 0;
out_7308457207715484996[1] = 0;
out_7308457207715484996[2] = 0;
out_7308457207715484996[3] = 0;
out_7308457207715484996[4] = 0;
out_7308457207715484996[5] = 0;
out_7308457207715484996[6] = 0;
out_7308457207715484996[7] = 0;
out_7308457207715484996[8] = 1;
void H_31(double *state, double *unused, double *out_7388463950973692759) {
out_7388463950973692759[0] = 0;
out_7388463950973692759[1] = 0;
out_7388463950973692759[2] = 0;
out_7388463950973692759[3] = 0;
out_7388463950973692759[4] = 0;
out_7388463950973692759[5] = 0;
out_7388463950973692759[6] = 0;
out_7388463950973692759[7] = 0;
out_7388463950973692759[8] = 1;
}
#include <eigen3/Eigen/Dense>
#include <iostream>
@@ -518,68 +518,68 @@ void car_update_28(double *in_x, double *in_P, double *in_z, double *in_R, doubl
void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea) {
update<1, 3, 0>(in_x, in_P, h_31, H_31, NULL, in_z, in_R, in_ea, MAHA_THRESH_31);
}
void car_err_fun(double *nom_x, double *delta_x, double *out_5825026556611430403) {
err_fun(nom_x, delta_x, out_5825026556611430403);
void car_err_fun(double *nom_x, double *delta_x, double *out_694062864366320957) {
err_fun(nom_x, delta_x, out_694062864366320957);
}
void car_inv_err_fun(double *nom_x, double *true_x, double *out_8876036798993240698) {
inv_err_fun(nom_x, true_x, out_8876036798993240698);
void car_inv_err_fun(double *nom_x, double *true_x, double *out_7656216431051591408) {
inv_err_fun(nom_x, true_x, out_7656216431051591408);
}
void car_H_mod_fun(double *state, double *out_6203949078932441352) {
H_mod_fun(state, out_6203949078932441352);
void car_H_mod_fun(double *state, double *out_2454126163912067491) {
H_mod_fun(state, out_2454126163912067491);
}
void car_f_fun(double *state, double dt, double *out_343822199527135251) {
f_fun(state, dt, out_343822199527135251);
void car_f_fun(double *state, double dt, double *out_1843607112126961388) {
f_fun(state, dt, out_1843607112126961388);
}
void car_F_fun(double *state, double dt, double *out_7416815269748566643) {
F_fun(state, dt, out_7416815269748566643);
void car_F_fun(double *state, double dt, double *out_2182262497468252920) {
F_fun(state, dt, out_2182262497468252920);
}
void car_h_25(double *state, double *unused, double *out_8641933420137717402) {
h_25(state, unused, out_8641933420137717402);
void car_h_25(double *state, double *unused, double *out_4798003278786560335) {
h_25(state, unused, out_4798003278786560335);
}
void car_H_25(double *state, double *unused, double *out_7339103169592445424) {
H_25(state, unused, out_7339103169592445424);
void car_H_25(double *state, double *unused, double *out_7357817989096732331) {
H_25(state, unused, out_7357817989096732331);
}
void car_h_24(double *state, double *unused, double *out_5501280400540853584) {
h_24(state, unused, out_5501280400540853584);
void car_h_24(double *state, double *unused, double *out_6970490004472512085) {
h_24(state, unused, out_6970490004472512085);
}
void car_H_24(double *state, double *unused, double *out_9067966288769759493) {
H_24(state, unused, out_9067966288769759493);
void car_H_24(double *state, double *unused, double *out_1156785309245570905) {
H_24(state, unused, out_1156785309245570905);
}
void car_h_30(double *state, double *unused, double *out_5706507355292462350) {
h_30(state, unused, out_5706507355292462350);
void car_h_30(double *state, double *unused, double *out_3972351172998717479) {
h_30(state, unused, out_3972351172998717479);
}
void car_H_30(double *state, double *unused, double *out_422412828100828669) {
H_30(state, unused, out_422412828100828669);
void car_H_30(double *state, double *unused, double *out_7228479041953492261) {
H_30(state, unused, out_7228479041953492261);
}
void car_h_26(double *state, double *unused, double *out_8743293406736795035) {
h_26(state, unused, out_8743293406736795035);
void car_h_26(double *state, double *unused, double *out_1029322094662128166) {
h_26(state, unused, out_1029322094662128166);
}
void car_H_26(double *state, double *unused, double *out_7366137585243049968) {
H_26(state, unused, out_7366137585243049968);
void car_H_26(double *state, double *unused, double *out_3616314670222676107) {
H_26(state, unused, out_3616314670222676107);
}
void car_h_27(double *state, double *unused, double *out_6768024602127501529) {
h_27(state, unused, out_6768024602127501529);
void car_h_27(double *state, double *unused, double *out_9195955360068189347) {
h_27(state, unused, out_9195955360068189347);
}
void car_H_27(double *state, double *unused, double *out_2597176139901253580) {
H_27(state, unused, out_2597176139901253580);
void car_H_27(double *state, double *unused, double *out_5053715730153067350) {
H_27(state, unused, out_5053715730153067350);
}
void car_h_29(double *state, double *unused, double *out_5090891545105754924) {
h_29(state, unused, out_5090891545105754924);
void car_h_29(double *state, double *unused, double *out_9038768691717060202) {
h_29(state, unused, out_9038768691717060202);
}
void car_H_29(double *state, double *unused, double *out_4310538866770804613) {
H_29(state, unused, out_4310538866770804613);
void car_H_29(double *state, double *unused, double *out_3340353003283516317) {
H_29(state, unused, out_3340353003283516317);
}
void car_h_28(double *state, double *unused, double *out_5824514749225839094) {
h_28(state, unused, out_5824514749225839094);
void car_h_28(double *state, double *unused, double *out_4249115445980516624) {
h_28(state, unused, out_4249115445980516624);
}
void car_H_28(double *state, double *unused, double *out_9053806189869216429) {
H_28(state, unused, out_9053806189869216429);
void car_H_28(double *state, double *unused, double *out_5303983274848842568) {
H_28(state, unused, out_5303983274848842568);
}
void car_h_31(double *state, double *unused, double *out_8917127482422223291) {
h_31(state, unused, out_8917127482422223291);
void car_h_31(double *state, double *unused, double *out_5644913485036226869) {
h_31(state, unused, out_5644913485036226869);
}
void car_H_31(double *state, double *unused, double *out_7308457207715484996) {
H_31(state, unused, out_7308457207715484996);
void car_H_31(double *state, double *unused, double *out_7388463950973692759) {
H_31(state, unused, out_7388463950973692759);
}
void car_predict(double *in_x, double *in_P, double *in_Q, double dt) {
predict(in_x, in_P, in_Q, dt);
+21 -21
View File
@@ -9,27 +9,27 @@ void car_update_27(double *in_x, double *in_P, double *in_z, double *in_R, doubl
void car_update_29(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void car_update_28(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void car_err_fun(double *nom_x, double *delta_x, double *out_5825026556611430403);
void car_inv_err_fun(double *nom_x, double *true_x, double *out_8876036798993240698);
void car_H_mod_fun(double *state, double *out_6203949078932441352);
void car_f_fun(double *state, double dt, double *out_343822199527135251);
void car_F_fun(double *state, double dt, double *out_7416815269748566643);
void car_h_25(double *state, double *unused, double *out_8641933420137717402);
void car_H_25(double *state, double *unused, double *out_7339103169592445424);
void car_h_24(double *state, double *unused, double *out_5501280400540853584);
void car_H_24(double *state, double *unused, double *out_9067966288769759493);
void car_h_30(double *state, double *unused, double *out_5706507355292462350);
void car_H_30(double *state, double *unused, double *out_422412828100828669);
void car_h_26(double *state, double *unused, double *out_8743293406736795035);
void car_H_26(double *state, double *unused, double *out_7366137585243049968);
void car_h_27(double *state, double *unused, double *out_6768024602127501529);
void car_H_27(double *state, double *unused, double *out_2597176139901253580);
void car_h_29(double *state, double *unused, double *out_5090891545105754924);
void car_H_29(double *state, double *unused, double *out_4310538866770804613);
void car_h_28(double *state, double *unused, double *out_5824514749225839094);
void car_H_28(double *state, double *unused, double *out_9053806189869216429);
void car_h_31(double *state, double *unused, double *out_8917127482422223291);
void car_H_31(double *state, double *unused, double *out_7308457207715484996);
void car_err_fun(double *nom_x, double *delta_x, double *out_694062864366320957);
void car_inv_err_fun(double *nom_x, double *true_x, double *out_7656216431051591408);
void car_H_mod_fun(double *state, double *out_2454126163912067491);
void car_f_fun(double *state, double dt, double *out_1843607112126961388);
void car_F_fun(double *state, double dt, double *out_2182262497468252920);
void car_h_25(double *state, double *unused, double *out_4798003278786560335);
void car_H_25(double *state, double *unused, double *out_7357817989096732331);
void car_h_24(double *state, double *unused, double *out_6970490004472512085);
void car_H_24(double *state, double *unused, double *out_1156785309245570905);
void car_h_30(double *state, double *unused, double *out_3972351172998717479);
void car_H_30(double *state, double *unused, double *out_7228479041953492261);
void car_h_26(double *state, double *unused, double *out_1029322094662128166);
void car_H_26(double *state, double *unused, double *out_3616314670222676107);
void car_h_27(double *state, double *unused, double *out_9195955360068189347);
void car_H_27(double *state, double *unused, double *out_5053715730153067350);
void car_h_29(double *state, double *unused, double *out_9038768691717060202);
void car_H_29(double *state, double *unused, double *out_3340353003283516317);
void car_h_28(double *state, double *unused, double *out_4249115445980516624);
void car_H_28(double *state, double *unused, double *out_5303983274848842568);
void car_h_31(double *state, double *unused, double *out_5644913485036226869);
void car_H_31(double *state, double *unused, double *out_7388463950973692759);
void car_predict(double *in_x, double *in_P, double *in_Q, double dt);
void car_set_mass(double x);
void car_set_rotational_inertia(double x);
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -5,18 +5,18 @@ void pose_update_4(double *in_x, double *in_P, double *in_z, double *in_R, doubl
void pose_update_10(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void pose_update_13(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void pose_update_14(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void pose_err_fun(double *nom_x, double *delta_x, double *out_4860250714300227404);
void pose_inv_err_fun(double *nom_x, double *true_x, double *out_6437944255548658708);
void pose_H_mod_fun(double *state, double *out_22797630451996970);
void pose_f_fun(double *state, double dt, double *out_2362837524605346595);
void pose_F_fun(double *state, double dt, double *out_4166989473592392013);
void pose_h_4(double *state, double *unused, double *out_800785631088066019);
void pose_H_4(double *state, double *unused, double *out_2555861026626074297);
void pose_h_10(double *state, double *unused, double *out_7585285090603906809);
void pose_H_10(double *state, double *unused, double *out_6341548427213940478);
void pose_h_13(double *state, double *unused, double *out_7888682643875678910);
void pose_H_13(double *state, double *unused, double *out_5768134851958407098);
void pose_h_14(double *state, double *unused, double *out_3441729687180753414);
void pose_H_14(double *state, double *unused, double *out_4925284788653666127);
void pose_err_fun(double *nom_x, double *delta_x, double *out_6507930050433723456);
void pose_inv_err_fun(double *nom_x, double *true_x, double *out_4828699442560272840);
void pose_H_mod_fun(double *state, double *out_6044345162965507958);
void pose_f_fun(double *state, double dt, double *out_2707422486897363634);
void pose_F_fun(double *state, double dt, double *out_2783420399776033045);
void pose_h_4(double *state, double *unused, double *out_6625322830489649201);
void pose_H_4(double *state, double *unused, double *out_891826777926427223);
void pose_h_10(double *state, double *unused, double *out_495585793918053605);
void pose_H_10(double *state, double *unused, double *out_8682725662931185277);
void pose_h_13(double *state, double *unused, double *out_6437595282912769194);
void pose_H_13(double *state, double *unused, double *out_2320447047405905578);
void pose_h_14(double *state, double *unused, double *out_1731855561045144303);
void pose_H_14(double *state, double *unused, double *out_1326943304571310822);
void pose_predict(double *in_x, double *in_P, double *in_Q, double dt);
}
Binary file not shown.
Binary file not shown.
@@ -4914,6 +4914,15 @@
"is_parent_toggle": true,
"settings_tier": "simple"
},
{
"key": "GalaxyMobileDefault",
"label": "Try the Big Dipper Web UI",
"description": "Open the Big Dipper at the top-level Galaxy link instead of the classic Galaxy. The classic UI remains available at /classic and Big Dipper at /mobile regardless of this toggle.",
"picker_description": "Serve the Big Dipper as the default landing page.",
"data_type": "bool",
"ui_type": "toggle",
"settings_tier": "advanced"
},
{
"key": "AlphaLongitudinalEnabled",
"label": "openpilot Longitudinal Control (Alpha)",
@@ -444,15 +444,26 @@ class SpeedLimitController:
return
current_road_name = sm["mapdOut"].roadName if desired_source == "Map Data" else ""
current_speed = self.target if (self.source != "None" and self.target > 0) else self.last_valid_limit
if abs(desired_target - self.previous_target) >= 1 or (current_road_name != self.previous_road_name and current_road_name != ""):
# Do not trigger alerts when shifting to fallback or when re-obtaining the same speed limit
is_fallback = desired_source == "None" or desired_target == 0
same_speed = desired_target > 0 and current_speed > 0 and abs(desired_target - current_speed) < 1
if not is_fallback and not same_speed and (abs(desired_target - self.previous_target) >= 1 or current_speed == 0):
self.handle_limit_change(desired_source, desired_target, current_road_name, v_ego, sm)
elif desired_source != self.source and (abs(desired_target - self.target) < 1 or self.target == 0):
self.source = desired_source
self.target = desired_target
else:
self.speed_limit_changed_timer = 0
self.unconfirmed_speed_limit = 0
if desired_source != self.source or desired_target != self.target:
self.source = desired_source
self.target = desired_target
if desired_source != "None" and desired_target > 0:
self.previous_source = desired_source
self.previous_target = desired_target
if current_road_name != self.previous_road_name and current_road_name != "":
self.previous_road_name = current_road_name
self.denied_target = 0
if self.source != "None" and self.target > 0:
self.last_valid_limit = self.target
@@ -342,6 +342,10 @@ ul { list-style: none; margin: 0; padding: 0; }
.gx-appbar__back:active { transform: scale(0.92); }
.gx-appbar__title {
background: linear-gradient(135deg, #8b6cc5 0%, #5ec8c8 55%, #d4789c 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
font-size: var(--fs-lg);
font-weight: var(--fw-bold);
white-space: nowrap;
@@ -7,7 +7,7 @@
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Galaxy">
<meta name="apple-mobile-web-app-title" content="Big Dipper">
<meta name="format-detection" content="telephone=no">
<meta name="theme-color" content="#8b6cc5" />
<link rel="manifest" href="/assets/mobile/manifest.json" crossorigin="use-credentials">
@@ -26,7 +26,7 @@
}
</script>
<title>Galaxy</title>
<title>Big Dipper</title>
</head>
<body>
@@ -105,11 +105,38 @@ export const api = {
deleteAllRoutes(includePreserved) { return request(`/api/routes/delete_all?include_preserved=${includePreserved}`, { method: "DELETE" }) },
getRouteLogs(name) { return request(`/api/routes/${encodeURIComponent(name)}/logs`) },
getScreenRecordings() { return request("/api/screen_recordings/list") },
async screenRecordingsStream({ onProgress, onRecordings, signal } = {}) {
const res = await fetch("/api/screen_recordings/list", { signal })
if (!res.ok || !res.body) throw new Error(`Screen recordings request failed (${res.status})`)
const reader = res.body.getReader()
const decoder = new TextDecoder()
let buffer = ""
while (true) {
const { value, done } = await reader.read()
if (done) break
buffer += decoder.decode(value, { stream: true })
const events = buffer.split(/\r?\n\r?\n/)
buffer = events.pop() || ""
for (const event of events) {
const lines = event.split(/\r?\n/).filter((l) => l.startsWith("data:"))
if (!lines.length) continue
try {
const payload = JSON.parse(lines.map((l) => l.slice(5).trimStart()).join("\n"))
if (Number.isFinite(payload.progress)) onProgress?.(payload.progress)
onRecordings?.(Array.isArray(payload.recordings) ? payload.recordings : [])
} catch (e) { }
}
}
},
screenRecordingVideoUrl(filename) { return `/api/screen_recordings/download/${encodeURIComponent(filename)}` },
deleteScreenRecording(filename) { return request(`/api/screen_recordings/delete/${encodeURIComponent(filename)}`, { method: "DELETE" }) },
deleteAllScreenRecordings() { return request("/api/screen_recordings/delete_all", { method: "DELETE" }) },
renameScreenRecording(oldName, newName) { return request("/api/screen_recordings/rename", { method: "POST", data: { old: oldName, new: newName } }) },
getModelLab() { return request("/api/model-laboratory", { cache: "no-store" }) },
saveModelLab(config) { return request("/api/model-laboratory", { method: "PUT", data: config }) },
prepareModelLabArtifact(model) { return request("/api/model-laboratory/download", { method: "POST", data: { model } }) },
getErrorLogs() { return request("/api/error_logs", { headers: { Accept: "application/json" } }) },
getErrorLog(filename) { return fetch(`/api/error_logs/${encodeURIComponent(filename)}`).then((r) => r.text()) },
deleteErrorLog(filename) { return delOk(`/api/error_logs/${encodeURIComponent(filename)}`) },
@@ -18,6 +18,7 @@ import { ModelManager } from "./views/ModelManager.js"
import { Plots } from "./views/Plots.js"
import { TestingGround } from "./views/TestingGround.js"
import { ThemeMaker } from "./views/ThemeMaker.js"
import { ModelLaboratory } from "./views/ModelLaboratory.js"
import { Cameras } from "./views/Cameras.js"
import { store, initRouter, navigate } from "./store.js"
import { showSnackbar } from "./api.js"
@@ -52,6 +53,7 @@ const VIEWS = {
"/plots": Plots,
"/testing_ground": TestingGround,
"/theme_maker": ThemeMaker,
"/model_laboratory": ModelLaboratory,
"/cameras": Cameras,
}
@@ -102,7 +102,7 @@ export const AppShell = {
<button type="button" class="gx-icon-btn gx-menu-btn" aria-label="Menu" @click="store.drawerOpen = true">
<i class="bi bi-list"></i>
</button>
<span class="gx-appbar__title">Galaxy</span>
<span class="gx-appbar__title">Big Dipper</span>
<div class="gx-searchwrap">
<input ref="searchInput" class="gx-search gx-appbar__search" type="search" placeholder="Search toggles..."
v-model="search" aria-label="Search toggles" />
@@ -128,8 +128,8 @@ export const AppShell = {
</transition>
<aside class="gx-drawer" :class="{ open: store.drawerOpen }">
<div class="gx-drawer__header">
<img class="gx-logo" src="/assets/images/main_logo.png" alt="Galaxy logo" />
<span class="gx-drawer-title">Galaxy</span>
<img class="gx-logo" src="/assets/images/main_logo.png" alt="Big Dipper logo" />
<span class="gx-drawer-title">Big Dipper</span>
</div>
<div class="gx-nav-section">
<div class="gx-nav-section__title">Main</div>
@@ -1,3 +1,5 @@
import { pwaState, requestInstall } from "../install.js"
export const FIRESTAR_HOST = "galaxy.firestar.link"
export function isFirestarOrigin() {
@@ -9,10 +11,6 @@ function isIos() {
return /iPad|iPhone|iPod/.test(ua) && !/CriOS|FxiOS|OPiOS|EdgiOS/.test(ua)
}
function isStandalone() {
return window.matchMedia("(display-mode: standalone)").matches || !!window.navigator.standalone
}
export const PwaInstallSection = {
name: "PwaInstallSection",
props: {
@@ -21,10 +19,8 @@ export const PwaInstallSection = {
},
data() {
return {
installed: isStandalone(),
isIos: isIos(),
onFirestar: isFirestarOrigin(),
deferredPrompt: null,
}
},
computed: {
@@ -35,33 +31,19 @@ export const PwaInstallSection = {
if (this.onFirestar) return window.location.origin
return ""
},
canInstall() { return !!this.deferredPrompt && !this.installed },
showManual() { return this.isIos && !this.installed && !this.deferredPrompt },
installed() { return pwaState.installed },
canInstall() { return !!pwaState.deferredPrompt && !pwaState.installed },
showManual() { return this.isIos && !pwaState.installed && !pwaState.deferredPrompt },
onLocal() { return !this.onFirestar && !this.installUrl },
},
methods: {
capturePrompt(e) {
e.preventDefault()
this.deferredPrompt = e
},
async install() {
const prompt = this.deferredPrompt
if (!prompt) return
prompt.prompt()
try { await prompt.userChoice } catch (e) { /* user cancelled */ }
this.deferredPrompt = null
this.installed = true
await requestInstall()
},
installHost() {
try { return new URL(this.installUrl).host } catch (e) { return this.installUrl }
},
},
mounted() {
window.addEventListener("beforeinstallprompt", this.capturePrompt)
},
beforeUnmount() {
window.removeEventListener("beforeinstallprompt", this.capturePrompt)
},
template: `
<section v-if="!installed" class="gx-card gx-install">
<div class="gx-section__header">
@@ -128,4 +110,4 @@ export const PwaInstallSection = {
</div>
</section>
`,
}
}
@@ -0,0 +1,30 @@
import { reactive } from "vue"
function inStandaloneMode() {
return window.matchMedia("(display-mode: standalone)").matches || !!window.navigator.standalone
}
export const pwaState = reactive({
deferredPrompt: null,
installed: inStandaloneMode(),
})
function capture(event) {
event.preventDefault()
pwaState.deferredPrompt = event
}
window.addEventListener("beforeinstallprompt", capture)
window.addEventListener("appinstalled", () => {
pwaState.deferredPrompt = null
pwaState.installed = true
})
export async function requestInstall() {
const prompt = pwaState.deferredPrompt
if (!prompt) return false
prompt.prompt()
try { await prompt.userChoice } catch (e) { /* user dismissed */ }
pwaState.deferredPrompt = null
return true
}
@@ -91,7 +91,7 @@ export function goBack() {
window.location.hash = prev
}
const NATIVE_ROOTS = new Set(["/", "/settings", "/tools", "/recordings", "/logs", "/tuning", "/navigation", "/vehicle", "/system", "/embed", "/manage_doors", "/galaxy", "/manage_tsk", "/sentry", "/manage_models", "/plots", "/testing_ground", "/theme_maker", "/cameras"])
const NATIVE_ROOTS = new Set(["/", "/settings", "/tools", "/recordings", "/logs", "/tuning", "/navigation", "/vehicle", "/system", "/embed", "/manage_doors", "/galaxy", "/manage_tsk", "/sentry", "/manage_models", "/plots", "/testing_ground", "/theme_maker", "/model_laboratory", "/cameras"])
export function toolHref(link) {
const path = link.split("?")[0]
@@ -196,7 +196,7 @@ export const Logs = {
</div>
<pre ref="tmuxtail" class="gx-terminal" @scroll.passive="onTmuxScroll">{{ stream.state.log || '(waiting for log output…)' }}</pre>
<div style="display:flex; gap:8px; padding: var(--sp-3); flex-wrap:wrap;">
<button type="button" class="gx-btn gx-btn--tonal" @click="stream.togglePause()">{{ stream.state.paused ? '▶️ Resume' : '⏸️ Pause' }}</button>
<button type="button" class="gx-btn gx-btn--tonal" @click="stream.togglePause()"><i class="bi" :class="stream.state.paused ? 'bi-play-fill' : 'bi-pause-fill'"></i> {{ stream.state.paused ? 'Resume' : 'Pause' }}</button>
<button type="button" class="gx-btn gx-btn--tonal" @click="captureTmux">Capture Log</button>
<button type="button" class="gx-btn gx-btn--tonal" @click="deleteAllTmux">Delete All</button>
</div>
@@ -0,0 +1,264 @@
import { api, showSnackbar } from "../api.js"
import { usePolling } from "../composables.js"
export const ModelLaboratory = {
name: "ModelLaboratory",
data() {
return {
loading: true,
saving: false,
error: "",
message: "",
dirty: false,
chestnutReady: false,
isOnroad: false,
configuration: { enabled: false, lateralModel: "", longitudinalModel: "" },
runtime: {},
summary: {},
models: [],
}
},
computed: {
readyModels() {
return this.models.filter((m) => m && m.modelLabArtifactAvailable)
},
candidates() {
const ready = this.readyModels
const lat = this.configuration.lateralModel
return ready.filter((m) => !lat || m.value !== lat)
},
selectionError() {
if (!this.chestnutReady) return "Connect a firmware-ready Chestnut first."
if (this.isOnroad) return "Park before changing the laboratory pair."
const lat = this.modelById(this.configuration.lateralModel)
const lon = this.modelById(this.configuration.longitudinalModel)
if (!lat || !lon) return "Choose two small models with published Chestnut artifacts."
if (lat.value === lon.value) return "Lateral and longitudinal models must be different."
if (!lat.modelLabArtifactAvailable || !lon.modelLabArtifactAvailable) {
return "Both models need a precompiled AMD artifact in the manifest."
}
if (!lat.modelLabArtifactInstalled || !lon.modelLabArtifactInstalled) {
return "Prepare both precompiled AMD artifacts first."
}
return ""
},
runtimeState() {
const r = this.runtime || {}
return r.active ? "Pair active" : r.requested ? "Pair requested" : "Inactive"
},
},
created() {
this.poll = usePolling(() => this.refresh(), { interval: 5000 })
this.poll.start()
},
beforeUnmount() {
this.poll?.destroy()
},
methods: {
modelById(id) {
return this.models.find((m) => m.value === id)
},
modelLabel(id) {
return this.modelById(id)?.label || id || "not selected"
},
artifactStatus(m) {
if (m.modelLabArtifactInstalled) return { text: "AMD ready", good: true }
if (m.modelLabArtifactAvailable) return { text: "AMD download needed", good: false }
return { text: "AMD not published", good: false }
},
async refresh() {
try {
const payload = await api.getModelLab()
this.applyPayload(payload)
} catch (e) {
this.error = e?.message || String(e)
} finally {
this.loading = false
}
},
applyPayload(payload) {
payload = payload || {}
this.chestnutReady = Boolean(payload.chestnutReady)
this.isOnroad = Boolean(payload.isOnroad)
this.error = String(payload.configurationError || "")
this.runtime = payload.runtime && typeof payload.runtime === "object" ? payload.runtime : {}
this.summary = payload.summary && typeof payload.summary === "object" ? payload.summary : {}
this.models = Array.isArray(payload.models) ? payload.models : []
const cfg = payload.configuration && typeof payload.configuration === "object" ? payload.configuration : {}
const draft = { ...this.configuration }
this.configuration = {
enabled: Boolean(cfg.enabled),
lateralModel: this.dirty ? draft.lateralModel : String(cfg.lateralModel || ""),
longitudinalModel: this.dirty ? draft.longitudinalModel : String(cfg.longitudinalModel || ""),
}
this.normalizeSelection()
},
normalizeSelection() {
const ready = this.readyModels
if (!this.modelById(this.configuration.lateralModel) && ready.length) {
this.configuration.lateralModel = ready[0].value
}
if (!this.modelById(this.configuration.longitudinalModel) && ready.length > 1) {
const lon = ready.find((m) => m.value !== this.configuration.lateralModel)
this.configuration.longitudinalModel = lon?.value || ""
}
},
onLateralChange() {
this.dirty = true
const lon = this.modelById(this.configuration.longitudinalModel)
const lat = this.modelById(this.configuration.lateralModel)
if (lon && lat && lon.value === lat.value) {
this.configuration.longitudinalModel = this.candidates[0]?.value || ""
}
},
async save(enabled) {
if (this.saving) return
if (enabled && this.selectionError) {
this.error = this.selectionError
return
}
this.saving = true
this.error = ""
this.message = ""
try {
const payload = await api.saveModelLab({
enabled,
lateralModel: this.configuration.lateralModel,
longitudinalModel: this.configuration.longitudinalModel,
})
this.dirty = false
this.applyPayload(payload)
this.message = String(payload?.message || "Model Laboratory configuration saved.")
showSnackbar("Model Laboratory saved", "info")
} catch (e) {
this.error = e?.message || String(e)
} finally {
this.saving = false
}
},
async prepareModel(modelId) {
if (this.saving || !modelId) return
this.saving = true
this.error = ""
this.message = ""
try {
const payload = await api.prepareModelLabArtifact(modelId)
this.message = String(payload?.message || "Chestnut artifact download queued.")
showSnackbar("Chestnut artifact download queued", "info")
await this.refresh()
} catch (e) {
this.error = e?.message || String(e)
} finally {
this.saving = false
}
},
},
template: `
<div class="gx-view">
<div v-if="loading" class="gx-card"><div class="gx-loading">Loading laboratory status...</div></div>
<template v-else>
<div class="gx-card">
<div class="gx-section__header">
<i class="bi bi-bezier2"></i>
<span class="gx-section__title">Model Laboratory</span>
<span class="gx-chip" :style="chestnutReady ? 'color:var(--success);' : 'color:var(--warning);'">{{ chestnutReady ? 'Chestnut ready' : 'Chestnut required' }}</span>
<span class="gx-chip" :style="isOnroad ? 'color:var(--warning);' : 'color:var(--success);'">{{ isOnroad ? 'Onroad · locked' : 'Parked · configurable' }}</span>
</div>
<div style="padding: 0 var(--sp-4) var(--sp-3); color:var(--text-muted); font-size:var(--fs-sm);">
Use the lateral judgment of one small model and the longitudinal judgment of another.
</div>
<div v-if="error" class="gx-alert" style="margin:0 var(--sp-4) var(--sp-3);">
<i class="bi bi-exclamation-triangle-fill" style="color:var(--error);"></i>
<div class="gx-alert__body"><span style="color:var(--error);">{{ error }}</span></div>
</div>
<div v-if="message" class="gx-alert gx-alert--info" style="margin:0 var(--sp-4) var(--sp-3);">
<i class="bi bi-check-circle-fill"></i>
<div class="gx-alert__body"><span>{{ message }}</span></div>
</div>
</div>
<div class="gx-card">
<div class="gx-section__header">
<i class="bi bi-collection"></i>
<span class="gx-section__title">Compose a pair</span>
<span class="gx-chip" :style="configuration.enabled ? 'background:var(--success);color:var(--on-secondary);' : ''">{{ configuration.enabled ? 'Enabled' : 'Disabled' }}</span>
</div>
<div style="padding: var(--sp-4); display:grid; gap:var(--sp-3);">
<label style="display:grid; gap:4px;">
<strong style="font-size:var(--fs-sm);">Lateral model</strong>
<small style="color:var(--text-muted); font-size:var(--fs-xs);">Path shape, curvature, lane geometry, and driving desire</small>
<select class="gx-field" :value="configuration.lateralModel" @change="configuration.lateralModel = $event.target.value; onLateralChange()">
<option value="">Choose a model</option>
<option v-for="m in readyModels" :key="m.value" :value="m.value">{{ m.label }} · {{ m.version }}</option>
</select>
</label>
<label style="display:grid; gap:4px;">
<strong style="font-size:var(--fs-sm);">Longitudinal model</strong>
<small style="color:var(--text-muted); font-size:var(--fs-xs);">Speed, acceleration, stopping, leads, and scene confidence</small>
<select class="gx-field" :value="configuration.longitudinalModel" @change="configuration.longitudinalModel = $event.target.value; dirty = true">
<option value="">Choose a model</option>
<option v-for="m in candidates" :key="m.value" :value="m.value">{{ m.label }} · {{ m.version }}</option>
</select>
</label>
<div style="display:flex; flex-wrap:wrap; gap:6px; align-items:center;">
<strong>{{ modelLabel(configuration.lateralModel) }}</strong><span class="gx-row__desc" style="margin:0;">steers</span>
<i class="bi bi-arrow-left-right"></i>
<strong>{{ modelLabel(configuration.longitudinalModel) }}</strong><span class="gx-row__desc" style="margin:0;">paces</span>
</div>
<p v-if="selectionError" class="gx-row__desc" style="margin:0; color:var(--warning);">{{ selectionError }}</p>
<div style="display:flex; gap:8px; flex-wrap:wrap;">
<button type="button" class="gx-btn" :disabled="saving || !!selectionError" @click="save(true)">
<i class="bi bi-play-fill"></i> Enable for next drive
</button>
<button type="button" class="gx-btn gx-btn--tonal" :disabled="saving || isOnroad || !configuration.enabled" @click="save(false)">
<i class="bi bi-stop-fill"></i> Disable
</button>
<button type="button" class="gx-btn gx-btn--tonal" :disabled="saving" @click="refresh">
<i class="bi bi-arrow-clockwise"></i> Refresh
</button>
</div>
</div>
</div>
<div class="gx-card">
<div class="gx-section__header">
<i class="bi bi-activity"></i>
<span class="gx-section__title">Runtime</span>
<span class="gx-chip" :style="runtime.active ? 'background:var(--success);color:var(--on-secondary);' : ''">{{ runtimeState }}</span>
</div>
<div style="padding: var(--sp-4); display:grid; gap:6px;">
<div class="gx-row" style="border-top:none;"><span class="gx-row__label">Lateral</span><span class="gx-row__value">{{ modelLabel(runtime.lateralModel) }}</span></div>
<div class="gx-row" style="border-top:none;"><span class="gx-row__label">Longitudinal</span><span class="gx-row__value">{{ modelLabel(runtime.longitudinalModel) }}</span></div>
<div v-if="runtime.error" class="gx-alert" style="margin:0;"><i class="bi bi-exclamation-triangle-fill" style="color:var(--error);"></i><div class="gx-alert__body"><span style="color:var(--error);">{{ runtime.error }}</span></div></div>
<p class="gx-row__desc" style="margin:0;">Both roles evaluate the same frame at 20 Hz. A runtime failure suppresses that frame and falls back to the built-in QCOM model.</p>
</div>
</div>
<div class="gx-card">
<div class="gx-section__header">
<i class="bi bi-cpu"></i>
<span class="gx-section__title">Available models</span>
<span class="gx-section__count">{{ summary.ready || 0 }} ready to pair · {{ Math.max((summary.published || 0) - (summary.ready || 0), 0) }} available to download</span>
</div>
<article v-for="m in readyModels" :key="m.value" class="gx-row">
<div class="gx-row__info">
<span class="gx-row__label">{{ m.label }}</span>
<span class="gx-row__desc">{{ m.value }} · {{ m.series || 'Unknown series' }}</span>
</div>
<div style="display:flex; gap:6px; flex-wrap:wrap; align-items:center;">
<span class="gx-chip">{{ m.version || 'unknown version' }}</span>
<span class="gx-chip">{{ m.modelSize || 'small' }}</span>
<span class="gx-chip" :style="artifactStatus(m).good ? 'color:var(--success);' : 'color:var(--warning);'">{{ artifactStatus(m).text }}</span>
<button v-if="m.modelLabArtifactAvailable && !m.modelLabArtifactInstalled" type="button" class="gx-btn gx-btn--tonal" :disabled="saving || isOnroad" @click="prepareModel(m.value)">
Prepare for Chestnut
</button>
</div>
</article>
<div style="padding: var(--sp-3);">
<p class="gx-row__desc" style="margin:0;">Model Manager downloads the manifest's precompiled AMD variants. Nothing is compiled on the comma. A normal installed model may still need its separate Chestnut artifact.</p>
</div>
</div>
</template>
</div>
`,
}
@@ -59,6 +59,8 @@ export const Pip = {
mounted() {
this._img = null
this._sizedFor = null
const canvas = this.canvas()
if (canvas) { canvas.width = CANVAS_W; canvas.height = CANVAS_H }
this.loadExistingConfig()
this.loadSnapshot()
this.$nextTick(() => this.redraw())
@@ -70,6 +72,14 @@ export const Pip = {
canvas() {
return this.$refs?.canvas || null
},
sizeCanvas() {
const canvas = this.canvas()
const img = this._img
if (!canvas || !img) return
const w = Math.min(img.naturalWidth, 1280)
canvas.width = w
canvas.height = Math.round(w * (img.naturalHeight / img.naturalWidth))
},
canvasScale() {
const canvas = this.canvas()
const img = this._img
@@ -165,8 +175,7 @@ export const Pip = {
const img = this._img
if (img && this._sizedFor !== img) {
this._sizedFor = img
canvas.width = Math.min(img.naturalWidth, 1280)
canvas.height = Math.round(canvas.width * (img.naturalHeight / img.naturalWidth))
this.sizeCanvas()
} else if (!img && (canvas.width === 0 || this._sizedFor)) {
this._sizedFor = null
canvas.width = CANVAS_W
@@ -257,6 +266,7 @@ export const Pip = {
this._sizedFor = null
this.image = true
this.success = "Camera snapshot loaded. Place a center point on each window, then adjust the zoom."
this.sizeCanvas()
this.applyConfigToCanvas()
this.redraw()
if (cleanup) cleanup()
@@ -1,7 +1,8 @@
import { api, showSnackbar } from "../api.js"
import { GalaxyConfirm } from "../components/GalaxyModal.js"
import { GalaxySection } from "../components/GalaxySection.js"
import { GalaxyTabs } from "../components/GalaxyTabs.js"
import { GxNotice } from "../components/GxNotice.js"
import { isFirestarOrigin } from "../components/PwaInstallSection.js"
function fmtDuration(seconds) {
seconds = Number(seconds) || 0
@@ -16,6 +17,26 @@ function formatBytes(bytes) {
return mb >= 1000 ? `${(mb / 1000).toFixed(2)} GB` : `${mb.toFixed(1)} MB`
}
function getOrdinalSuffix(n) {
const s = ["th", "st", "nd", "rd"]
const v = n % 100
return s[(v - 20) % 10] || s[v] || s[0]
}
function formatScreenDate(dateString) {
const date = new Date(dateString)
if (Number.isNaN(date.getTime())) return String(dateString || "Unknown date")
const month = date.toLocaleString("en-US", { month: "long" })
const day = date.getDate()
const year = date.getFullYear()
let hour = date.getHours()
const minute = date.getMinutes()
const ampm = hour >= 12 ? "pm" : "am"
hour = hour % 12 || 12
const minuteStr = minute < 10 ? "0" + minute : minute
return `${month} ${day}${getOrdinalSuffix(day)}, ${year} - ${hour}:${minuteStr}${ampm}`
}
function normalizeRoute(r) {
const name = String(r?.name || "")
const isCustomName = !!r?.isCustomName
@@ -33,9 +54,10 @@ function normalizeRoute(r) {
export const Recordings = {
name: "Recordings",
components: { GalaxySection, GalaxyTabs },
components: { GalaxyTabs, GxNotice },
data() {
return {
sub: "routes",
loading: true,
error: "",
routes: [],
@@ -52,6 +74,13 @@ export const Recordings = {
selectedCamera: "",
logsRoute: null,
logsData: null,
onFirestar: isFirestarOrigin(),
// Screen recordings subtab
screenLoading: false,
screenError: "",
screenProgress: 0,
recordings: [],
recPlay: null,
}
},
computed: {
@@ -81,6 +110,13 @@ export const Recordings = {
methods: {
fmtDuration,
formatBytes,
setSub(key) {
this.sub = key === "screen" ? "screen" : "routes"
if (this.sub === "screen" && !this.recordings.length && !this.screenLoading) this.loadScreenRecordings()
},
screenDisplayName(rec) {
return rec.is_custom_name ? rec.filename.replace(/\.mp4$/i, "").replace(/_/g, " ") : formatScreenDate(rec.timestamp)
},
async loadRoutes() {
this.loading = true
this.error = ""
@@ -107,6 +143,35 @@ export const Recordings = {
this.loading = false
}
},
async loadScreenRecordings() {
this.screenLoading = true
this.screenError = ""
this.recordings = []
this.screenProgress = 0
const seen = new Set()
try {
this.recController?.abort()
this.recController = new AbortController()
await api.screenRecordingsStream({
signal: this.recController.signal,
onProgress: (p) => { this.screenProgress = p },
onRecordings: (raw) => {
for (const r of raw) {
if (seen.has(r.filename)) continue
seen.add(r.filename)
this.recordings.push(r)
}
},
})
} catch (e) {
if (e?.name !== "AbortError") this.screenError = "Couldn't load recordings."
} finally {
this.screenLoading = false
}
},
refreshScreenRecordings() {
this.loadScreenRecordings()
},
async deleteRoute(route) {
if (!(await GalaxyConfirm({ title: "Delete route?", message: `Delete “${route.displayName}”?`, confirmLabel: "Delete", danger: true }))) return
try {
@@ -148,13 +213,14 @@ export const Recordings = {
this.routes = []
showSnackbar(payload?.message || "Routes deleted!")
} catch (e) {
showSnackbar("Failed to delete routes.", "error")
showSnackbar(e?.message || "Failed to delete routes.", "error")
}
},
async openPlayer(route) {
this.playerRoute = route
this.playerLoading = true
this.playerError = ""
this._playRetries = 0
try {
const data = await api.getRoute(route.name)
const segments = Array.isArray(data.segment_urls) ? data.segment_urls.filter((u) => typeof u === "string") : []
@@ -173,13 +239,23 @@ export const Recordings = {
}
},
cameraUrl(url, low) {
if (this.selectedCamera === "forward") return low && !url.includes("?" ) ? `${url}?quality=low` : url
if (this.selectedCamera === "forward") return low && !url.includes("?") ? `${url}?quality=low` : url
const sep = url.includes("?") ? "&" : "?"
return `${url}${sep}camera=${encodeURIComponent(this.selectedCamera)}${low ? "&quality=low" : ""}`
},
playSegment() {
const video = this.$refs.player
if (!video || !this.segments[this.current]) return
if (!this.segments[this.current]) return
// The player mounts inside a Teleport + transition after openPlayer clears
// playerLoading, so the video element may not exist on the very first call.
if (!video) {
this._playRetries = (this._playRetries || 0) + 1
if (this._playRetries <= 15) {
requestAnimationFrame(() => this.playSegment())
}
return
}
this._playRetries = 0
video.src = this.cameraUrl(this.segments[this.current])
video.load()
video.play().catch(() => {})
@@ -192,6 +268,7 @@ export const Recordings = {
a.click()
},
closePlayer() {
this._playRetries = 0
if (this.$refs.player) { this.$refs.player.pause(); this.$refs.player.removeAttribute("src") }
this.playerRoute = null
this.playerLoading = false
@@ -207,13 +284,71 @@ export const Recordings = {
showSnackbar("Could not read logs.", "error")
}
},
closeRecPlayer() {
this.recPlay = null
},
screenUrl(filename) {
return api.screenRecordingVideoUrl(filename)
},
playRec(rec) {
this.recPlay = rec
},
downloadRec(rec) {
const a = document.createElement("a")
a.href = api.screenRecordingVideoUrl(rec.filename)
a.download = rec.filename
a.click()
},
async renameRec(rec) {
const base = rec.filename.replace(/\.mp4$/i, "")
const val = prompt("Rename recording:", base)
if (!val || val === base) return
try {
await api.renameScreenRecording(rec.filename, val + ".mp4")
showSnackbar("Recording renamed!")
this.refreshScreenRecordings()
} catch (e) {
showSnackbar("Rename failed.", "error")
}
},
async deleteRec(rec) {
if (!(await GalaxyConfirm({ title: "Delete recording?", message: `Delete “${rec.filename}”?`, confirmLabel: "Delete", danger: true }))) return
try {
await api.deleteScreenRecording(rec.filename)
this.recordings = this.recordings.filter((r) => r.filename !== rec.filename)
if (this.recPlay?.filename === rec.filename) this.recPlay = null
showSnackbar("Recording deleted!")
} catch (e) {
showSnackbar("Delete failed.", "error")
}
},
async deleteAllRecs() {
if (!(await GalaxyConfirm({ title: "Delete all recordings?", message: "This permanently deletes every screen recording.", confirmLabel: "Delete All", danger: true }))) return
try {
const payload = await api.deleteAllScreenRecordings()
this.recordings = []
this.recPlay = null
showSnackbar(payload?.message || "All screen recordings deleted!")
} catch (e) {
showSnackbar(e?.message || "Delete failed.", "error")
}
},
},
async mounted() {
if (!this.onFirestar) await this.loadRoutes()
},
beforeUnmount() {
this.controller?.abort()
this.recController?.abort()
},
async mounted() { await this.loadRoutes() },
beforeUnmount() { this.controller?.abort() },
template: `
<div>
<template v-if="!onFirestar">
<h2 style="margin-top:0;">Recordings</h2>
<GalaxyTabs :items="{ routes: 'Dashcam Routes', screen: 'Screen Recordings' }" :active="sub" @select="setSub" />
<template v-if="sub === 'routes'">
<section class="gx-card">
<div class="gx-section__header">
<i class="bi bi-camera-reels"></i>
@@ -277,10 +412,47 @@ export const Recordings = {
<a class="gx-btn gx-btn--tonal" :href="seg.url" download>Download</a>
</div>
</div>
</template>
<template v-else>
<section class="gx-card">
<div class="gx-section__header">
<i class="bi bi-record-circle"></i>
<span class="gx-section__title">Screen Recordings</span>
<span class="gx-section__count">{{ recordings.length }}</span>
</div>
<div v-if="screenLoading && !recordings.length" class="gx-loading">Loading screen recordings...</div>
<div v-else-if="screenError" class="gx-empty" style="color: var(--error);">{{ screenError }}</div>
<div v-else-if="!recordings.length" class="gx-empty">No screen recordings found.</div>
<article v-for="r in recordings" :key="r.filename" class="gx-row" style="cursor:pointer;" @click="playRec(r)">
<img :src="r.png" alt="" loading="lazy" style="width:84px; height:auto; border-radius:var(--radius-sm); object-fit:cover; flex:none;">
<div class="gx-row__info">
<span class="gx-row__label">{{ screenDisplayName(r) }}</span>
<span class="gx-row__desc">{{ r.filename }}</span>
</div>
<div style="display:flex; gap:6px; flex-wrap:wrap;">
<button type="button" class="gx-btn gx-btn--tonal" title="Play" @click.stop="playRec(r)"><i class="bi bi-play-fill"></i></button>
<button type="button" class="gx-btn gx-btn--tonal" title="Rename" @click.stop="renameRec(r)"><i class="bi bi-pencil"></i></button>
<button type="button" class="gx-btn gx-btn--tonal" title="Download" @click.stop="downloadRec(r)"><i class="bi bi-download"></i></button>
<button type="button" class="gx-btn gx-btn--danger" title="Delete" @click.stop="deleteRec(r)"><i class="bi bi-trash"></i></button>
</div>
</article>
</section>
<section class="gx-card" v-if="recordings.length">
<div class="gx-section__header">
<i class="bi bi-exclamation-triangle"></i>
<span class="gx-section__title">Delete recordings</span>
</div>
<div style="display:flex; gap:8px; padding: var(--sp-3); flex-wrap:wrap;">
<button type="button" class="gx-btn gx-btn--danger" @click="deleteAllRecs">Delete All Recordings</button>
</div>
</section>
</template>
<Teleport to="body">
<transition name="gx-fade">
<div v-if="playerRoute" class="gx-scrim gx-scrim--bottomsheet" @click.self="closePlayer">
<div v-if="sub === 'routes' && playerRoute" class="gx-scrim gx-scrim--bottomsheet" @click.self="closePlayer">
<div class="gx-sheet" role="dialog" aria-label="Route video player">
<div class="gx-section__header" style="cursor:default;">
<i class="bi bi-camera-video"></i>
@@ -307,6 +479,32 @@ export const Recordings = {
</div>
</transition>
</Teleport>
<Teleport to="body">
<transition name="gx-fade">
<div v-if="recPlay" class="gx-scrim gx-scrim--bottomsheet" @click.self="closeRecPlayer">
<div class="gx-sheet" role="dialog" aria-label="Screen recording player">
<div class="gx-section__header" style="cursor:default;">
<i class="bi bi-record-circle"></i>
<span class="gx-section__title">{{ screenDisplayName(recPlay) }}</span>
<button type="button" class="gx-icon-btn" aria-label="Close player" @click="closeRecPlayer"><i class="bi bi-x-lg"></i></button>
</div>
<div style="padding: var(--sp-3);">
<video class="gx-video" controls autoplay playsinline :src="screenUrl(recPlay.filename)"></video>
<div style="display:flex; gap:8px; padding: var(--sp-3) 0 0; flex-wrap:wrap;">
<button type="button" class="gx-btn" @click="downloadRec(recPlay)"><i class="bi bi-download"></i> Download</button>
<button type="button" class="gx-btn gx-btn--tonal" @click="renameRec(recPlay)"><i class="bi bi-pencil"></i> Rename</button>
<button type="button" class="gx-btn gx-btn--danger" @click="deleteRec(recPlay)"><i class="bi bi-trash"></i> Delete</button>
</div>
</div>
</div>
</div>
</transition>
</Teleport>
</template>
<GxNotice v-else tone="info" icon="bi-satellite" title="Recordings Unavailable via Galaxy"
text="Loading recordings requires a direct connection. Connect to your device's local network to use this feature." />
</div>
`,
}
@@ -267,7 +267,7 @@ export const SystemTools = {
<div v-if="fastStatus.message" class="gx-note">{{ fastStatus.message }}</div>
<div v-if="fastStatus.warning && (fastStatus.running || fastStatus.updateAvailable)" class="gx-note gx-note--danger">{{ fastStatus.warning }}</div>
<div v-if="fastStatus.agnosUpdate?.available && fastStatus.agnosUpdate?.warnings?.length" style="margin-top:4px;">
<div v-for="w in fastStatus.agnosUpdate.warnings" :key="w" class="gx-note gx-note--danger"> {{ w }}</div>
<div v-for="w in fastStatus.agnosUpdate.warnings" :key="w" class="gx-note gx-note--danger"><i class="bi bi-exclamation-triangle-fill"></i> {{ w }}</div>
</div>
</div>
</div>

Some files were not shown because too many files have changed in this diff Show More