
#include "press_down_detect.h"

#define down_thresh 2000

#define BIG_WINDOW_SIZE 20

int back_jump_stage = 0;

int cancel_down = 0;
int virus_flag = 0;

float real_front_min_left = 50000;
float real_front_min_right = 50000;


void dual_foot_detect_up_trend(uint16_t* left_mag_up_min, uint16_t*left_up_count, uint16_t* left_mag_window,
	uint16_t* right_mag_up_min, uint16_t*right_up_count , uint16_t* right_mag_window, int window_size, int RESET_SIGNAL, int up_thesh)
{
	uint16_t left_max_val = left_mag_window[window_size - 1];
	uint16_t left_min_val = left_mag_window[window_size - 1];
	int16_t left_max_index = window_size - 1;
	int16_t left_min_index = window_size - 1;

	uint16_t right_max_val = right_mag_window[window_size - 1];
	uint16_t right_min_val = right_mag_window[window_size - 1];
	
	int16_t right_max_index = window_size - 1;
	int16_t right_min_index = window_size - 1;

	for (int i = window_size -1; i > 1; i--)
	{
		if (left_mag_window[i] >= left_mag_window[i - 1] + up_thesh && left_mag_window[i] < left_mag_window[i - 1] + 1000
			&& right_mag_window[i] >= right_mag_window[i - 1] + up_thesh && right_mag_window[i] < right_mag_window[i - 1] + 1000)
		{
			if (left_max_val < left_mag_window[i])
			{
				left_max_val = left_mag_window[i];
				left_max_index = i;
			}

		if (left_min_val > left_mag_window[i])
		{
			left_min_val = left_mag_window[i];
			left_min_index = i;
		}

		if (right_max_val < right_mag_window[i])
		{
			right_max_val = right_mag_window[i];
			right_max_index = i;
		}

			if (right_min_val > right_mag_window[i])
			{
				right_min_val = right_mag_window[i];
				right_min_index = i;
			}
		}
		else
		{
			break;
		}
	}

	if ((left_max_val - left_min_val > 100 && left_max_index > left_min_index && left_max_val - left_mag_window[window_size - 1] < 100) &&
		(right_max_val - right_min_val > 100 && right_max_index > right_min_index && right_max_val - right_mag_window[window_size - 1] < 100)
		&&((RESET_SIGNAL && right_mag_window[window_size - 1] < right_mag_window[window_size - 2] + 1000 
		&& left_mag_window[window_size - 1]  < left_mag_window[window_size - 2] + 1000)
			|| !RESET_SIGNAL))
	{
		if (*left_up_count > 0)
		{
			*left_up_count = *left_up_count + 1;


			if (left_min_val < *left_mag_up_min)
			{
				*left_mag_up_min = left_min_val;
			}
		}
		else
		{ 
			int index = left_min_index > right_min_index ? left_min_index : right_min_index;

			*left_mag_up_min = left_mag_window[index];

			for (int i = 0; i <= index; i++)
			{
				left_mag_window[i] = left_mag_window[index];
			}

			*left_up_count = window_size - index;
		}

		if (*right_up_count > 0)
		{
			*right_up_count = *right_up_count + 1;

			if (right_min_val < *right_mag_up_min)
			{
				*right_mag_up_min = right_min_val;
			}
		}
		else
		{
			int index = left_min_index > right_min_index ? left_min_index : right_min_index;

			*right_mag_up_min = right_mag_window[index];

			for (int i = 0; i <= index; i++)
			{
				right_mag_window[i] = right_mag_window[index];
			}

			*right_up_count = window_size - index;
		}


	}
	else
	{
		*left_mag_up_min = 40000;
		*right_mag_up_min = 40000;

		*left_up_count = 0;
		*right_up_count = 0;

		//重置窗口数据
		//if (RESET_SIGNAL &&((right_mag_window[window_size - 1] > right_mag_window[window_size - 2] + 1000)
		//	|| (left_mag_window[window_size - 1] > left_mag_window[window_size - 2] + 1000)))
		///*if (RESET_SIGNAL && ((right_mag_window[window_size - 1] > right_mag_window[window_size - 2] + 1000)
		//	|| (left_mag_window[window_size - 1] > left_mag_window[window_size - 2] + 1000)))*/
		//{

		//	memset(right_mag_window, right_mag_window[window_size - 1], window_size * sizeof(uint16_t));
		//	memset(left_mag_window, left_mag_window[window_size - 1], window_size * sizeof(uint16_t));
		//}
		
	

	}


}

int avoid_down_during_change_road(float* left_mag_window, float* right_mag_window, int window_size)
{
	float left_max_val = left_mag_window[0];
	float left_min_val = left_mag_window[0];
	int left_max_index = 0;
	int left_min_index = 0;

	float right_max_val = right_mag_window[0];
	float right_min_val = right_mag_window[0];
	int right_max_index = 0;
	int right_min_index = 0;

	for (int i = 1; i < window_size; i++)
	{
		if (left_max_val < left_mag_window[i])
		{
			left_max_val = left_mag_window[i];
			left_max_index = i;
		}

		if (left_min_val > left_mag_window[i])
		{
			left_min_val = left_mag_window[i];
			left_min_index = i;
		}

		if (right_max_val < right_mag_window[i])
		{
			right_max_val = right_mag_window[i];
			right_max_index = i;
		}

		if (right_min_val > right_mag_window[i])
		{
			right_min_val = right_mag_window[i];
			right_min_index = i;
		}
	}

	if (left_max_index > left_min_index && right_max_index < right_min_index
		&& left_max_val - left_min_val > 2000.f && right_max_val - right_min_val > 2000.f)
	{
		return 1;
	}

	if (left_max_index < left_min_index && right_max_index > right_min_index
		&& left_max_val - left_min_val > 2000.f && right_max_val - right_min_val > 2000.f)
	{
		return 1;
	}

	return 0;
}

int avoid_down_during_change_road_by_acc(int16_t* left_acc_window, int16_t* right_acc_window, int window_size, int threshold)
{
	int16_t left_max_val = left_acc_window[window_size - 1];
	int16_t left_min_val = left_acc_window[window_size - 1];


	int16_t right_max_val = right_acc_window[window_size - 1];
	int16_t right_min_val = right_acc_window[window_size - 1];

	for (int i = BIG_WINDOW_SIZE - 1; i >= BIG_WINDOW_SIZE - window_size; i--)
	{
		if (left_max_val < left_acc_window[i])
		{
			left_max_val = left_acc_window[i];
		}

		if (left_min_val > left_acc_window[i])
		{
			left_min_val = left_acc_window[i];

		}

		if (right_max_val < right_acc_window[i])
		{
			right_max_val = right_acc_window[i];
		}

		if (right_min_val > right_acc_window[i])
		{
			right_min_val = right_acc_window[i];
		}
	}

	//if (left_max_val > left_min_val + 0.3f || right_max_val > right_min_val + 0.3f)
	if (left_max_val > left_min_val + threshold || right_max_val > right_min_val + threshold) // 0.1
	{
		return 1;
	}

	return 0;
}



int press_down_detect_new(int index, uint16_t front_mag_left, uint16_t back_mag_left,
	uint16_t front_mag_right, uint16_t back_mag_right, int16_t left_zupt, int16_t right_zupt,
	int16_t left_acc_x, int16_t left_acc_y, int16_t left_acc_z,
	int16_t right_acc_x, int16_t right_acc_y, int16_t right_acc_z,
	int16_t* front_down, int16_t* back_down)
{

	static uint16_t front_mag_left_big_buff[BIG_WINDOW_SIZE];
	static uint16_t front_mag_right_big_buff[BIG_WINDOW_SIZE];

	static uint16_t back_mag_left_big_buff[BIG_WINDOW_SIZE];
	static uint16_t back_mag_right_big_buff[BIG_WINDOW_SIZE];

	static int16_t left_acc_z_big_buff[BIG_WINDOW_SIZE];
	static int16_t right_acc_z_big_buff[BIG_WINDOW_SIZE];

	static uint16_t left_front_up_min = 40000;
	static uint16_t left_back_up_min = 40000;

	static uint16_t right_front_up_min = 40000;
	static uint16_t right_back_up_min = 40000;

	static uint16_t left_front_up_count = 0;
	static uint16_t right_front_up_count = 0;

	static uint16_t left_back_up_count = 0;
	static uint16_t right_back_up_count = 0;


	memcpy(front_mag_left_big_buff, front_mag_left_big_buff + 1, (BIG_WINDOW_SIZE - 1) * sizeof(uint16_t));
	memcpy(front_mag_right_big_buff, front_mag_right_big_buff + 1, (BIG_WINDOW_SIZE - 1) * sizeof(uint16_t));

	memcpy(back_mag_left_big_buff, back_mag_left_big_buff + 1, (BIG_WINDOW_SIZE - 1) * sizeof(uint16_t));
	memcpy(back_mag_right_big_buff, back_mag_right_big_buff + 1, (BIG_WINDOW_SIZE - 1) * sizeof(uint16_t));

	memcpy(left_acc_z_big_buff,  left_acc_z_big_buff + 1,  (BIG_WINDOW_SIZE - 1) * sizeof(int16_t));
	memcpy(right_acc_z_big_buff, right_acc_z_big_buff + 1, (BIG_WINDOW_SIZE - 1) * sizeof(int16_t));

	front_mag_left_big_buff[(BIG_WINDOW_SIZE - 1)] = front_mag_left;
	front_mag_right_big_buff[(BIG_WINDOW_SIZE - 1)] = front_mag_right;


	back_mag_left_big_buff[(BIG_WINDOW_SIZE - 1)] = back_mag_left;
	back_mag_right_big_buff[(BIG_WINDOW_SIZE - 1)] = back_mag_right;

	left_acc_z_big_buff[(BIG_WINDOW_SIZE - 1)] = left_acc_z;
	right_acc_z_big_buff[(BIG_WINDOW_SIZE - 1)] = right_acc_z;


	dual_foot_detect_up_trend(&left_front_up_min, &left_front_up_count, front_mag_left_big_buff,
		&right_front_up_min, &right_front_up_count, front_mag_right_big_buff, BIG_WINDOW_SIZE, 1, -50);

	dual_foot_detect_up_trend(&left_back_up_min, &left_back_up_count, back_mag_left_big_buff,
		&right_back_up_min, &right_back_up_count, back_mag_right_big_buff, BIG_WINDOW_SIZE, 0, -100);

	
	//if (front_mag_left - left_front_up_min > 2000 && front_mag_right - right_front_up_min > 2000)
	if (front_mag_left - left_front_up_min > 1000 && front_mag_right - right_front_up_min > 1000 
		&& front_mag_left_big_buff[BIG_WINDOW_SIZE - 1] > front_mag_left_big_buff[BIG_WINDOW_SIZE - 2]
		&& front_mag_right_big_buff[BIG_WINDOW_SIZE - 1] > front_mag_right_big_buff[BIG_WINDOW_SIZE - 2])
	{
		*front_down = 1;

		//printf( "left_front_up_count: %d , right_front_up_count : %d \n" , left_front_up_count , right_front_up_count);
	}




	//if (back_mag_left - left_back_up_min > 3000 && back_mag_right - right_back_up_min > 3000)
	if (back_mag_left - left_back_up_min > 2000 && back_mag_right - right_back_up_min > 2000
		&& back_mag_left_big_buff[BIG_WINDOW_SIZE - 1] > back_mag_left_big_buff[BIG_WINDOW_SIZE - 2]
		&& back_mag_right_big_buff[BIG_WINDOW_SIZE - 1] > back_mag_right_big_buff[BIG_WINDOW_SIZE - 2])
	{
		*back_down = 1;

		//printf("left_front_up_count: %d , right_front_up_count : %d \n", left_front_up_count , right_front_up_count);
	}



	if (avoid_down_during_change_road_by_acc(left_acc_z_big_buff, right_acc_z_big_buff, BIG_WINDOW_SIZE/2, 250))
	{
		if (*front_down == 1)
		{
			//printf("delete front_down when change road \n");
		}

		if (*back_down == 1)
		{
			//printf("delete back_down when change road \n");
		}
		*front_down = 0;
		*back_down = 0;
	}

//	if (!avoid_down_during_change_road_by_acc(left_acc_z_big_buff, right_acc_z_big_buff, BIG_WINDOW_SIZE/2, 100))
//	{
//		/*if (front_mag_left - left_front_up_min > 500 && front_mag_right - right_front_up_min > 500)
//		{
//			*front_down = 1;
//		}*/

//		if (back_mag_left - left_back_up_min > 1000 && back_mag_right - right_back_up_min > 1000)
//		{

//			*back_down = 1;
//		}
//	}


	return 0;
}

short pos_jump_detect(int* h_pos, int* s_pos, int left_zupt, int right_zupt)
{
	static int last_h_z;
	static int last_s_z;
	static int left_up;
	static int right_up;

	static int left_up_count;
	static int right_up_count;


	static int left_zupt_count;
	static int right_zupt_count;

	if (left_zupt)
	{
		left_zupt_count = 10;
	}
	else
	{
		left_zupt_count--;
	}

	if (right_zupt)
	{
		right_zupt_count = 10;
	}
	else
	{
		right_zupt_count--;
	}



	if (h_pos[2] - last_h_z > 0 && h_pos[2] > 0)
	{
		left_up = 1;
	}
	else if ((h_pos[2] - last_h_z < 0) || h_pos[2] <= 0)
	{
		left_up = -1;
	}

	if (left_up == 1)
	{
		left_up_count++;
	}
	else
	{
		left_up_count = 0;
	}

	if (s_pos[2] - last_s_z > 0 && s_pos[2] > 0)
	{
		right_up = 1;
	}
	else if ((s_pos[2] - last_s_z < 0) || s_pos[2] <= 0)
	{
		right_up = -1;
	}

	if (right_up == 1)
	{
		right_up_count++;
	}
	else
	{
		right_up_count = 0;
	}

	last_h_z = h_pos[2];
	last_s_z = s_pos[2];

	if (left_up == 1 && right_up == 1 && right_up_count < 15 && left_up_count < 15
		&& right_zupt_count > 0 && left_zupt_count > 0 &&
		((right_up_count > 2 && left_up_count > 2) ||
			(right_up_count > 0 && left_up_count > 0 && h_pos[2] > 15 && s_pos[2] > 15)))
	{
		return 1;
	}

	return 0;

}

//由于仅靠IMU来探测触底了，高度估计得不太对，所以用加速度来算起跳动作

void max_min_window(float* data, int length, float* max_val, int* max_index, float* min_val, int* min_index)
{
	*max_val = data[0];

	*max_index = 0;

	*min_val = data[0];

	*min_index = 0;

	for (int i = 0; i < length; i++)
	{
		if (*max_val < data[i])
		{
			*max_val = data[i];
			*max_index = i;
		}

		if (*min_val > data[i])
		{
			*min_val = data[i];
			*min_index = i;
		}
	}


}

int avoid_error_jump_by_press(float* mag_window, int window_size)
{
	float min_val = mag_window[0];
	float max_val = mag_window[0];

	int max_index = 0;

	
	for (int i = 0; i < window_size; i++)
	{
		if (min_val > mag_window[0])
		{
			min_val = mag_window[0];
		}

		if (max_val < mag_window[0])
		{
			max_val = mag_window[0];
			max_index = i;
		}
	}

	if (max_val - min_val > 2000.f && max_index == window_size - 1)
	{
		return 1;
	}

	return 0;
}

short press_jump_detect(float left_acc_z, float right_acc_z, int left_zupt, int right_zupt, int left_front_press, int right_front_press)
{

	static float right_data_z_buff[10];
	static float left_data_z_buff[10];

	static float left_front_mag_buff[10];
	static float right_front_mag_buff[10];

	static int press_wait;
	static int acc_wait;



	/*
	* 存储数据
	*/
	memcpy(right_data_z_buff, right_data_z_buff + 1, 9 * sizeof(float));

	memcpy(left_data_z_buff, left_data_z_buff + 1, 9 * sizeof(float));

	right_data_z_buff[9] = right_acc_z;

	left_data_z_buff[9] = left_acc_z;



	memcpy(left_front_mag_buff, left_front_mag_buff + 1, 9 * sizeof(float));
	memcpy(right_front_mag_buff, right_front_mag_buff + 1, 9 * sizeof(float));

	left_front_mag_buff[9] = left_front_press;

	right_front_mag_buff[9] = right_front_press;

	float max_val_right_mag, min_val_right_mag, max_val_left_mag, min_val_left_mag;

	int max_index_right_mag, min_index_right_mag, max_index_left_mag, min_index_left_mag;

	max_min_window(right_front_mag_buff, 10, &max_val_right_mag, &max_index_right_mag, &min_val_right_mag, &min_index_right_mag);

	max_min_window(left_front_mag_buff, 10, &max_val_left_mag, &max_index_left_mag, &min_val_left_mag, &min_index_left_mag);

	if (max_val_right_mag > right_front_press + 3000.f && max_val_left_mag > left_front_press + 3000.f)
	{
		int start_index = max_index_left_mag > max_index_right_mag ? max_index_left_mag : max_index_right_mag;
		
		int down_flag = 1;
		// 遍历双脚持续下降的所用
		for (int i = start_index + 1; i < 10; i++)
		{
			if (right_front_mag_buff[i - 1] - right_front_mag_buff[i] < 100.f)
			{
				down_flag = 0;
				break;
			}
			if (left_front_mag_buff[i - 1] - left_front_mag_buff[i] < 100.f)
			{
				down_flag = 0;
				break;
			}
		}
		
		if (down_flag == 1)
		{
			press_wait = 10;
		}
	}


	/*
	* 加速变化估计
	*/

	float max_val_right, min_val_right, max_val_left, min_val_left;

	int max_index_right, min_index_right, max_index_left, min_index_left;


	max_min_window(right_data_z_buff, 10, &max_val_right, &max_index_right, &min_val_right, &min_index_right);

	max_min_window(left_data_z_buff, 10, &max_val_left, &max_index_left, &min_val_left, &min_index_left);


	/*
	* 1.0f的阈值轻轻跳就可以达到了,现在改为1.3f的阈值
	*/

	int jump = 0;
	if (max_index_right < min_index_right && max_index_left < min_index_left

		&& max_val_right - min_val_right > 0.8f && max_val_left - min_val_left > 0.8f 

		&& (left_zupt == 0 && right_zupt == 0))

	{
		acc_wait = 10;
	}

	if ( acc_wait > 0 && press_wait > 0)
	{
		jump = 1;
	}

	if (acc_wait > 0)
	{
		acc_wait--;
	}

	if (press_wait > 0)
	{
		press_wait--;
	}

	//if (avoid_error_jump_by_press(left_front_mag_buff, 10))
	//{
	//	jump = 0;
	//}

	//if (avoid_error_jump_by_press(right_front_mag_buff, 10))
	//{
	//	jump = 0;
	//}

	return jump;

}

int att_jump_detect(float left_pitch, float right_pitch, int left_zupt, int right_zupt)
{

	static int num;

	static float left_pitch_window[8];
	static float right_pitch_window[8];

	//用俯仰角判断好了, 现在的IMU方向 下标1为俯仰角
	memcpy(left_pitch_window, left_pitch_window + 1, 7 * sizeof(float));
	memcpy(right_pitch_window, right_pitch_window + 1, 7 * sizeof(float));

	left_pitch_window[7] = left_pitch;
	right_pitch_window[7] = right_pitch;

	num++;

	if (num < 8)
	{
		return 0;
	}
	else
	{
		num = 8;
	}
	//要求起跳要同步

	static int zupt_count = 0;
	if (left_zupt && right_zupt)
	{
		zupt_count = 21;
	}

	if (zupt_count > 0)
	{
		zupt_count--;
	}

	for (int i = 7; i > 1; i--)
	{
		if ((left_pitch_window[i] > left_pitch_window[i - 1] || left_pitch_window[i] > left_pitch_window[i - 2])
			&& (right_pitch_window[i] > right_pitch_window[i - 1] || right_pitch_window[i] > right_pitch_window[i - 2]))
		{
			if ((left_pitch > left_pitch_window[i - 1] + 0.1f || left_pitch > left_pitch_window[i - 2] + 0.1f)
				&& (right_pitch > right_pitch_window[i - 1] + 0.1f || right_pitch > right_pitch_window[i - 2] + 0.1f)
				&& zupt_count > 0)
			{
				return 1;
			}

		}
		else
		{
			return 0;
		}
	}

	return 0;
}
