Jelajahi Sumber

Add pausing of tracking.

k4be 2 tahun lalu
induk
melakukan
8dd078bd99
5 mengubah file dengan 160 tambahan dan 62 penghapusan
  1. 8 5
      soft/display.c
  2. 70 46
      soft/gpx.c
  3. 2 0
      soft/main.h
  4. 76 10
      soft/working_modes.c
  5. 4 1
      soft/working_modes.h

+ 8 - 5
soft/display.c

@@ -127,6 +127,7 @@ __flash const char _gps_wait[] =		"Czekam na GPS...";
 __flash const char _gps_ok[] =			"GPS OK!";
 __flash const char _card_ok[] =			"Karta OK!";
 __flash const char _logging_active[] =	"Zapis aktywny";
+__flash const char _logging_paused[] =	"Zapis wstrzymany";
 
 void disp_func_card_ok(__attribute__ ((unused)) unsigned char changed) {
 	strcpy_P(disp.line1, _card_ok);
@@ -142,9 +143,12 @@ void disp_func_file_closed(__attribute__ ((unused)) unsigned char changed) {
 }
 
 void disp_func_main_default(__attribute__ ((unused)) unsigned char changed) {
-	if (FLAGS & F_FILEOPEN)
-		strcpy_P(disp.line1, _logging_active);
-	else
+	if (FLAGS & F_FILEOPEN) {
+		if (System.tracking_paused)
+			strcpy_P(disp.line1, _logging_paused);
+		else
+			strcpy_P(disp.line1, _logging_active);
+	} else
 		strcpy_P(disp.line1, _card_ok);
 
 	if (FLAGS & F_GPSOK)
@@ -175,8 +179,7 @@ void disp_func_ele_sat(__attribute__ ((unused)) unsigned char changed) {
 }
 
 void disp_func_main_menu(__attribute__ ((unused)) unsigned char changed) {
-	strcpy_P(disp.line1, PSTR("  *** MENU *** "));
-	strcpy_P(disp.line2, PSTR("> Ustawienia"));
+	display_main_menu_item();
 }
 
 void disp_func_settings_menu(__attribute__ ((unused)) unsigned char changed) {

+ 70 - 46
soft/gpx.c

@@ -33,55 +33,62 @@ struct kalman_s {
 #define AVG_COUNT	3
 #define MIN_DIST_DELTA	2.0
 
-struct {
+struct prev_points_s {
 	struct location_s data[PREV_POINTS_LENGTH];
 	unsigned char start;
 	unsigned char count;
-} prev_points;
-struct location_s last_saved;
+};
 
-static struct kalman_s kalman[2];
-static struct {
+struct avg_store_s {
 	float lat;
 	float lon;
 	time_t time;
-} avg_store;
-static unsigned char avg_count;
+};
 
+static struct {
+	struct prev_points_s prev_points;
+	unsigned char avg_count;
+	unsigned char paused;
+	struct avg_store_s avg_store;
+	struct location_s last_saved;
+	struct kalman_s kalman[2];
+} gpx;
 
 float kalman_predict(struct kalman_s *k, float data);
 void kalman_init(struct kalman_s *k);
 float distance(struct location_s *pos1, struct location_s *pos2);
 
 void prev_points_append(struct location_s *new){
-	prev_points.data[(prev_points.start + prev_points.count)%PREV_POINTS_LENGTH] = *new;
-	if(++prev_points.count > PREV_POINTS_LENGTH){
-		prev_points.count--;
-		prev_points.start++;
-		prev_points.start %= PREV_POINTS_LENGTH;
+	gpx.prev_points.data[(gpx.prev_points.start + gpx.prev_points.count)%PREV_POINTS_LENGTH] = *new;
+	if(++gpx.prev_points.count > PREV_POINTS_LENGTH){
+		gpx.prev_points.count--;
+		gpx.prev_points.start++;
+		gpx.prev_points.start %= PREV_POINTS_LENGTH;
 	}
 }
 
 struct location_s *prev_points_get(unsigned char index){
-	unsigned char i, addr = prev_points.start;
+	unsigned char i, addr = gpx.prev_points.start;
 	for(i=0; i<index; i++){
 		addr++;
 		addr %= PREV_POINTS_LENGTH;
 	}
-	return &prev_points.data[addr];
+	return &gpx.prev_points.data[addr];
 }
 
 
 unsigned char gpx_init(FIL *file) {
 	unsigned int bw;
 	
-	kalman_init(&kalman[0]);
-	kalman_init(&kalman[1]);
-	prev_points.count = 0;
-	avg_count = 0;	
-	last_saved.lon = 0;
-	last_saved.lat = 0;
-	last_saved.time = 0;
+	kalman_init(&gpx.kalman[0]);
+	kalman_init(&gpx.kalman[1]);
+	gpx.prev_points.count = 0;
+	gpx.avg_count = 0;
+	gpx.last_saved.lon = 0;
+	gpx.last_saved.lat = 0;
+	gpx.last_saved.time = 0;
+
+	gpx.paused = 0;
 
 	strcpy_P(buf, xml_header);
 	return f_write(file, buf, strlen(buf), &bw);
@@ -90,17 +97,34 @@ unsigned char gpx_init(FIL *file) {
 unsigned char gpx_write(struct location_s *loc, FIL *file) {
 	unsigned int bw;
 	const char *time;
-	
-	time = get_iso_time(loc->time, 0);
-	xsprintf(buf, PSTR("\t\t\t<trkpt lat=\"%.8f\" lon=\"%.8f\">\n\t\t\t\t<time>%s</time>\n"), loc->lat, loc->lon, time);
-	/* alt */
-	strcat_P(buf, PSTR("\t\t\t</trkpt>\n"));
+
+	if (System.tracking_paused) {
+		if (!gpx.paused) {
+			strcpy_P(buf, PSTR("\t\t</trkseg>\n"));
+			gpx.paused = 1;
+		} else {
+			return 0; /* nothing to store */
+		}
+	} else {
+		if (gpx.paused) {
+			strcpy_P(buf, PSTR("\t\t<trkseg>\n"));
+			f_write(file, buf, strlen(buf), &bw);
+			gpx.paused = 0;
+		}
+		time = get_iso_time(loc->time, 0);
+		xsprintf(buf, PSTR("\t\t\t<trkpt lat=\"%.8f\" lon=\"%.8f\">\n\t\t\t\t<time>%s</time>\n"), loc->lat, loc->lon, time);
+		/* alt */
+		strcat_P(buf, PSTR("\t\t\t</trkpt>\n"));
+	}
 	return f_write(file, buf, strlen(buf), &bw);
 }
 
 unsigned char gpx_close(FIL *file) {
 	unsigned int bw;
-	strcpy_P(buf, PSTR("\t\t</trkseg>\n\t</trk>\n</gpx>\n"));
+	buf[0] = '\0';
+	if (!gpx.paused)
+		strcpy_P(buf, PSTR("\t\t</trkseg>\n"));
+	strcat_P(buf, PSTR("\t</trk>\n</gpx>\n"));
 	f_write(file, buf, strlen(buf), &bw);
 	return f_close(file);
 }
@@ -114,8 +138,8 @@ void gpx_process_point(struct location_s *loc, FIL *file){
 		xputs_P(PSTR("Write with filters disabled\r\n"));
 		gpx_write(loc, file);
 	} else {
-		lat_est = kalman_predict(&kalman[0], loc->lat);
-		lon_est = kalman_predict(&kalman[1], loc->lon);
+		lat_est = kalman_predict(&gpx.kalman[0], loc->lat);
+		lon_est = kalman_predict(&gpx.kalman[1], loc->lon);
 		
 		lat_err = fabs(loc->lat - lat_est);
 		lon_err = fabs(loc->lon - lon_est);
@@ -128,7 +152,7 @@ void gpx_process_point(struct location_s *loc, FIL *file){
 		loc->lon = lon_est;
 		
 		prev_points_append(loc);
-		if(prev_points.count == PREV_POINTS_LENGTH){
+		if(gpx.prev_points.count == PREV_POINTS_LENGTH){
 			float dist12 = distance(prev_points_get(0), prev_points_get(1));
 			float dist34 = distance(prev_points_get(2), prev_points_get(3));
 			float dist32 = distance(prev_points_get(2), prev_points_get(1));
@@ -139,35 +163,35 @@ void gpx_process_point(struct location_s *loc, FIL *file){
 			}
 			ptr = prev_points_get(PREV_POINTS_LENGTH - 2);
 		} else {
-			if(prev_points.count >= PREV_POINTS_LENGTH-2){
-				ptr = prev_points_get(prev_points.count - 2);
+			if(gpx.prev_points.count >= PREV_POINTS_LENGTH-2){
+				ptr = prev_points_get(gpx.prev_points.count - 2);
 				xputs_P(PSTR("NEW\r\n"));
 			} else {
 				return;
 			}
 		}
 
-		if(distance(&last_saved, ptr) < MIN_DIST_DELTA){
+		if(distance(&gpx.last_saved, ptr) < MIN_DIST_DELTA){
 			xputs_P(PSTR("Too small position change REJECT\r\n"));
 			return;
 		}
 
 		xputs_P(PSTR("ACCEPT\r\n"));
 
-		avg_store.lat += ptr->lat;
-		avg_store.lon += ptr->lon;
-		if(avg_count == AVG_COUNT/2)
-			avg_store.time = ptr->time;
+		gpx.avg_store.lat += ptr->lat;
+		gpx.avg_store.lon += ptr->lon;
+		if(gpx.avg_count == AVG_COUNT/2)
+			gpx.avg_store.time = ptr->time;
 		
-		if(++avg_count == AVG_COUNT){
-			nloc.lat = avg_store.lat / AVG_COUNT;
-			nloc.lon = avg_store.lon / AVG_COUNT;
-			nloc.time = avg_store.time;
-			avg_count = 0;
-			avg_store.lat = 0;
-			avg_store.lon = 0;
-			avg_store.time = 0;
-			last_saved = nloc;
+		if(++gpx.avg_count == AVG_COUNT){
+			nloc.lat = gpx.avg_store.lat / AVG_COUNT;
+			nloc.lon = gpx.avg_store.lon / AVG_COUNT;
+			nloc.time = gpx.avg_store.time;
+			gpx.avg_count = 0;
+			gpx.avg_store.lat = 0;
+			gpx.avg_store.lon = 0;
+			gpx.avg_store.time = 0;
+			gpx.last_saved = nloc;
 			gpx_write(&nloc, file);
 			return;
 		}

+ 2 - 0
soft/main.h

@@ -127,6 +127,7 @@ struct timers {
 	unsigned int system_log;
 	unsigned int lcd;
 	unsigned int backlight;
+	unsigned int info_display;
 };
 
 struct system_s {
@@ -145,6 +146,7 @@ struct system_s {
 	unsigned sbas:1;
 	unsigned gps_initialized:1;
 	unsigned gps_only:1;
+	unsigned tracking_paused:1;
 };
 
 struct location_s {

+ 76 - 10
soft/working_modes.c

@@ -14,9 +14,67 @@ __flash const unsigned char main_display_modes[] = {
 	DISPLAY_STATE_ELE_SAT,
 };
 
-__flash const struct main_menu_pos_s main_menu[] = {
+const char *enter_settings_get_name(void) {
+	return PSTR("> Ustawienia");
+}
+
+unsigned char tracking_pause(void) {
+	System.tracking_paused = !System.tracking_paused;
+	if (System.tracking_paused)
+		LEDB_ON();
+	else
+		LEDB_OFF();
+	return MODE_NO_CHANGE;
+}
+
+#define STATE_PAUSE_TRACKING_NOTPAUSED	0
+#define STATE_PAUSE_TRACKING_JUSTPAUSED	1
+#define STATE_PAUSE_TRACKING_PAUSED		2
+#define STATE_PAUSE_TRACKING_JUSTUNPAUSED	3
+
+const char *pause_tracking_get_name(void) {
+	static unsigned char state = STATE_PAUSE_TRACKING_NOTPAUSED;
+	switch (state) {
+		default:
+		case STATE_PAUSE_TRACKING_NOTPAUSED:
+			if (System.tracking_paused) {
+				set_timer(info_display, 2000);
+				state = STATE_PAUSE_TRACKING_JUSTPAUSED;
+			}
+			return PSTR("> Wstrzymaj rej.");
+		case STATE_PAUSE_TRACKING_JUSTPAUSED:
+			if (timer_expired(info_display))
+				state = STATE_PAUSE_TRACKING_PAUSED;
+			if (!System.tracking_paused) {
+				set_timer(info_display, 2000);
+				state = STATE_PAUSE_TRACKING_JUSTUNPAUSED;
+			}
+			return PSTR("Wstrzymano!");
+		case STATE_PAUSE_TRACKING_PAUSED:
+			if (!System.tracking_paused) {
+				set_timer(info_display, 2000);
+				state = STATE_PAUSE_TRACKING_JUSTUNPAUSED;
+			}
+			return PSTR("> Wznow rejestr.");
+		case STATE_PAUSE_TRACKING_JUSTUNPAUSED:
+			if (System.tracking_paused) {
+				set_timer(info_display, 2000);
+				state = STATE_PAUSE_TRACKING_JUSTPAUSED;
+			}
+			if (timer_expired(info_display))
+				state = STATE_PAUSE_TRACKING_NOTPAUSED;
+			return PSTR("Wznowiono!");
+	}
+}
+
+__flash const struct main_menu_pos_s main_menu[MAIN_MENU_MAXPOS+1] = {
 	{
 		.func = enter_settings,
+		.get_name = enter_settings_get_name,
+	},
+	{
+		.func = tracking_pause,
+		.get_name = pause_tracking_get_name,
 	},
 };
 
@@ -50,9 +108,17 @@ unsigned char working_mode_main_menu(unsigned char k) {
 		case K_LEFT:
 			return MODE_DEFAULT;
 		case K_RIGHT:
-			return main_menu_right_press();
-		case K_DOWN: /* TODO next menu item */
-		case K_UP: /* TODO prev menu item */
+			if (main_menu[mp.main_menu_pos].func)
+				return main_menu[mp.main_menu_pos].func();
+			break;
+		case K_DOWN:
+			if (mp.main_menu_pos < MAIN_MENU_MAXPOS)
+				mp.main_menu_pos++;
+			break;
+		case K_UP:
+			if (mp.main_menu_pos > 0)
+				mp.main_menu_pos--;
+			break;
 	}
 	display_state(DISPLAY_STATE_MAIN_MENU);
 	return MODE_NO_CHANGE;
@@ -82,6 +148,12 @@ unsigned char working_mode_settings_menu(unsigned char k) {
 	return MODE_NO_CHANGE;
 }
 
+
+void display_main_menu_item(void) {
+	strcpy_P(disp.line1, PSTR("  *** MENU *** "));
+	strcpy_P(disp.line2, main_menu[mp.main_menu_pos].get_name());
+}
+
 void display_settings_menu_item(void) {
 	switch (settings_menu[mp.settings_menu_pos].type) {
 		case SETTINGS_TYPE_BOOL:
@@ -116,12 +188,6 @@ void key_process(void) {
 	}
 }
 
-unsigned char main_menu_right_press(void) {
-	if (main_menu[mp.main_menu_pos].func)
-		return main_menu[mp.main_menu_pos].func();
-	return MODE_NO_CHANGE;
-}
-
 unsigned char enter_settings(void) {
 	display_state(DISPLAY_STATE_SETTINGS_MENU);
 	return MODE_SETTINGS_MENU;

+ 4 - 1
soft/working_modes.h

@@ -5,7 +5,10 @@
 #define MODE_MAIN_MENU	1
 #define MODE_SETTINGS_MENU	2
 
+#define MAIN_MENU_MAXPOS 1
+
 struct main_menu_pos_s {
+	const char * (* get_name)(void);
 	unsigned char (* func)(void);
 };
 
@@ -17,7 +20,7 @@ struct menu_params_s {
 extern struct menu_params_s mp;
 
 void key_process(void);
-unsigned char main_menu_right_press(void);
 unsigned char enter_settings(void);
 void display_settings_menu_item(void);
+void display_main_menu_item(void);