Skip to content

Commit

Permalink
Head Tilt Alarm (hd-zero#390)
Browse files Browse the repository at this point in the history
* Tilt alarm, and settings sub page

* Faster tilt response

* Conformation when setting alarm angle

* Set angle conformation is now like recalibrating

* Fixed crash on Back
IDV7 authored Mar 14, 2024
1 parent be38310 commit 49d5937
Showing 8 changed files with 261 additions and 32 deletions.
1 change: 1 addition & 0 deletions src/core/elrs.c
Original file line number Diff line number Diff line change
@@ -278,6 +278,7 @@ void msp_process_packet() {
msp_send_packet(MSP_GET_REC_STATE, MSP_PACKET_RESPONSE, 1, &buf);
} break;
case MSP_SET_REC_STATE: {
g_setting.ht.alarm_on_arm = packet.payload[0];
if (g_app_state == APP_STATE_VIDEO) {
record_state = packet.payload[0] == 0 ? 1 : 2;
uint32_t delay = packet.payload[1] | (uint32_t)packet.payload[2] << 8;
41 changes: 41 additions & 0 deletions src/core/ht.c
Original file line number Diff line number Diff line change
@@ -49,7 +49,10 @@ static const int ppmMaxPulse = 500;
static const int ppmMinPulse = -500;
static const int ppmCenter = 1500;

static pthread_t head_alarm_handle;

static void calculate_orientation();
static void *head_alarm_thread(void *arg);

///////////////////////////////////////////////////////////////////////////////
// no motion to disable OLED display
@@ -239,6 +242,11 @@ void ht_set_maxangle(int angle) {
ht_data.panFactor = 1000.0 / angle;
}

void ht_set_alarm_angle() {
g_setting.ht.alarm_angle = ht_data.tiltAngle;
ini_putl("ht", "alarm_angle", g_setting.ht.alarm_angle, SETTING_INI);
}

static void calc_gyr(float *gyrAngle) // in degree
{
// convert gyro readings to degrees/sec (with calibration offsets)
@@ -356,3 +364,36 @@ void ht_disable() {
int16_t *ht_get_channels() {
return ht_data.htChannels;
}

void head_alarm_init() {
pthread_create(&head_alarm_handle, NULL, head_alarm_thread, NULL);
}

void *head_alarm_thread(void *arg) {
while (1) {
bool sounding_alarm = false;
if (ht_data.enable && (g_setting.ht.alarm_state != SETTING_HT_ALARM_STATE_OFF)) { // user settings
if ((g_setting.ht.alarm_on_arm && g_setting.ht.alarm_state == SETTING_HT_ALARM_STATE_ARM) || (g_setting.ht.alarm_on_video && g_setting.ht.alarm_state == SETTING_HT_ALARM_STATE_VIDEO)) { // system enabling alarm (when armed or has video signal)

if (ht_data.tiltAngle < g_setting.ht.alarm_angle) {
beep();
usleep(100000);
beep();
for (int i = 0; i < 30; i++) { // delay of 3 seconds split into 30x100ms to allow for a quicker response to the alarm
if (ht_data.tiltAngle >= g_setting.ht.alarm_angle) {
break;
}
usleep(100000);
}
}

usleep(150000); // prevent resource occupation (when armed or video)
} else {
usleep(250000); // prevent resource occupation (when !armed and/or !video)
}
} else {
sleep(3); // prevent resource occupation (when ht and/or alarm is disabled)
}
}
pthread_exit(NULL);
}
2 changes: 2 additions & 0 deletions src/core/ht.h
Original file line number Diff line number Diff line change
@@ -55,8 +55,10 @@ void ht_disable();
void ht_detect_motion();
void ht_calibrate();
void ht_set_maxangle(int angle);
void ht_set_alarm_angle();
void ht_set_center_position();
int16_t *ht_get_channels();
void head_alarm_init();

#ifdef __cplusplus
}
3 changes: 3 additions & 0 deletions src/core/main.c
Original file line number Diff line number Diff line change
@@ -191,6 +191,9 @@ int main(int argc, char *argv[]) {
// 8.1 set initial analog module power state
Analog_Module_Power(0);

// Head alarm
head_alarm_init();

// 10. Execute main loop
g_init_done = 1;
for (;;) {
8 changes: 8 additions & 0 deletions src/core/settings.c
Original file line number Diff line number Diff line change
@@ -65,6 +65,12 @@ const setting_t g_setting_defaults = {
.gyr_x = 0,
.gyr_y = 0,
.gyr_z = 0,
.alarm_state = SETTING_HT_ALARM_STATE_OFF,
.alarm_angle = 1300,
.alarm_delay = 5,
.alarm_pattern = SETTING_HT_ALARM_PATTERN_2SHORT,
.alarm_on_arm = false,
.alarm_on_video = false,
},
.elrs = {
.enable = false,
@@ -403,6 +409,8 @@ void settings_load(void) {
g_setting.ht.gyr_x = ini_getl("ht", "gyr_x", g_setting_defaults.ht.gyr_x, SETTING_INI);
g_setting.ht.gyr_y = ini_getl("ht", "gyr_y", g_setting_defaults.ht.gyr_y, SETTING_INI);
g_setting.ht.gyr_z = ini_getl("ht", "gyr_z", g_setting_defaults.ht.gyr_z, SETTING_INI);
g_setting.ht.alarm_state = ini_getl("ht", "alarm_state", g_setting_defaults.ht.alarm_state, SETTING_INI);
g_setting.ht.alarm_angle = ini_getl("ht", "alarm_angle", g_setting_defaults.ht.alarm_angle, SETTING_INI);

// elrs
g_setting.elrs.enable = settings_get_bool("elrs", "enable", g_setting_defaults.elrs.enable);
18 changes: 18 additions & 0 deletions src/core/settings.h
Original file line number Diff line number Diff line change
@@ -54,6 +54,18 @@ typedef enum {
SETTING_POWER_WARNING_TYPE_BOTH = 2
} setting_power_warning_type_t;

typedef enum {
SETTING_HT_ALARM_STATE_OFF = 0,
SETTING_HT_ALARM_STATE_VIDEO = 1,
SETTING_HT_ALARM_STATE_ARM = 2,
} setting_ht_alarm_state_t;

typedef enum {
SETTING_HT_ALARM_PATTERN_1SHORT = 0,
SETTING_HT_ALARM_PATTERN_2SHORT = 1,
SETTING_HT_ALARM_PATTERN_1LONG = 2
} setting_ht_alarm_pattern_t;

typedef struct {
int voltage;
bool display_voltage;
@@ -102,6 +114,12 @@ typedef struct {
int32_t gyr_x;
int32_t gyr_y;
int32_t gyr_z;
setting_ht_alarm_state_t alarm_state;
int alarm_angle;
uint16_t alarm_delay;
setting_ht_alarm_pattern_t alarm_pattern;
bool alarm_on_arm;
bool alarm_on_video;
} setting_head_tracker_t;

typedef struct {
19 changes: 12 additions & 7 deletions src/core/thread.c
Original file line number Diff line number Diff line change
@@ -78,6 +78,17 @@ static void check_hdzero_signal(int vtmg_change) {
tune_channel_timer();
}

if (g_source_info.source == SOURCE_AV_IN)
is_valid = g_source_info.av_in_status;
else if (g_source_info.source == SOURCE_EXPANSION)
is_valid = g_source_info.av_bay_status;
else
is_valid = (rx_status[0].rx_valid || rx_status[1].rx_valid);

if (g_setting.ht.alarm_state == SETTING_HT_ALARM_STATE_VIDEO) {
g_setting.ht.alarm_on_video = is_valid;
}

// exit if no SD card or not in video mode
if (g_setting.record.mode_manual || (!g_sdcard_enable) || (g_app_state != APP_STATE_VIDEO))
return;
@@ -103,19 +114,13 @@ static void check_hdzero_signal(int vtmg_change) {
cnt = 0;
}

if (g_source_info.source == SOURCE_AV_IN)
is_valid = g_source_info.av_in_status;
else if (g_source_info.source == SOURCE_EXPANSION)
is_valid = g_source_info.av_bay_status;
else
is_valid = (rx_status[0].rx_valid || rx_status[1].rx_valid);

if (dvr_is_recording) { // in-recording
if (!is_valid) {
cnt++;
if (cnt >= SIGNAL_LOSS_DURATION_THR) {
cnt = 0;
LOGI("Signal lost");
g_setting.ht.alarm_on_video = false;
dvr_cmd(DVR_STOP);
}
} else
Loading

0 comments on commit 49d5937

Please sign in to comment.