Commit bd30e7cb authored by 957dd's avatar 957dd

Merge branch 'feature/add_0207tankyouhua' into 'master'

Feature/add 0207tankyouhua See merge request !91
parents ff97f015 c08ca4d0
...@@ -96,6 +96,7 @@ int hash_insert_init(HashTable_t *HashTable_t) { ...@@ -96,6 +96,7 @@ int hash_insert_init(HashTable_t *HashTable_t) {
insert(HashTable_t, "0203", TANK_0203); insert(HashTable_t, "0203", TANK_0203);
insert(HashTable_t, "0204", TANK_0204); insert(HashTable_t, "0204", TANK_0204);
insert(HashTable_t, "0206", TANK_0206); insert(HashTable_t, "0206", TANK_0206);
insert(HashTable_t, "0207", TANK_0207);
insert(HashTable_t, "0301", SHIP_0301); insert(HashTable_t, "0301", SHIP_0301);
insert(HashTable_t, "0401", PAO_0401); insert(HashTable_t, "0401", PAO_0401);
insert(HashTable_t, "0403", PGGPS_0403); insert(HashTable_t, "0403", PGGPS_0403);
...@@ -127,6 +128,9 @@ int device_judg(CodeEnum_t code,char *sub_str) { ...@@ -127,6 +128,9 @@ int device_judg(CodeEnum_t code,char *sub_str) {
}else if(code == TANK_0206) { }else if(code == TANK_0206) {
device_init(DEVICE_TANK0206); device_init(DEVICE_TANK0206);
my_zlog_info("使用水坦克,型号%s",sub_str); my_zlog_info("使用水坦克,型号%s",sub_str);
}else if(code == TANK_0207) {
device_init(DEVICE_TANK0207);
my_zlog_info("使用射水弹坦克,型号%s",sub_str);
}else if(code == SHIP_0301) { }else if(code == SHIP_0301) {
device_init(DEVICE_SHIP0301); device_init(DEVICE_SHIP0301);
my_zlog_info("使用34号船,型号%s",sub_str); my_zlog_info("使用34号船,型号%s",sub_str);
......
...@@ -17,6 +17,7 @@ typedef enum { ...@@ -17,6 +17,7 @@ typedef enum {
TANK_0203, TANK_0203,
TANK_0204, TANK_0204,
TANK_0206, TANK_0206,
TANK_0207,
SHIP_0301, SHIP_0301,
PAO_0401, PAO_0401,
PGGPS_0403, PGGPS_0403,
......
...@@ -809,6 +809,30 @@ drivers/devicecontrol/tank0206_control.c.s: ...@@ -809,6 +809,30 @@ drivers/devicecontrol/tank0206_control.c.s:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/devicecontrol/tank0206_control.c.s $(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/devicecontrol/tank0206_control.c.s
.PHONY : drivers/devicecontrol/tank0206_control.c.s .PHONY : drivers/devicecontrol/tank0206_control.c.s
drivers/devicecontrol/tank0207_control.o: drivers/devicecontrol/tank0207_control.c.o
.PHONY : drivers/devicecontrol/tank0207_control.o
# target to build an object file
drivers/devicecontrol/tank0207_control.c.o:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/devicecontrol/tank0207_control.c.o
.PHONY : drivers/devicecontrol/tank0207_control.c.o
drivers/devicecontrol/tank0207_control.i: drivers/devicecontrol/tank0207_control.c.i
.PHONY : drivers/devicecontrol/tank0207_control.i
# target to preprocess a source file
drivers/devicecontrol/tank0207_control.c.i:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/devicecontrol/tank0207_control.c.i
.PHONY : drivers/devicecontrol/tank0207_control.c.i
drivers/devicecontrol/tank0207_control.s: drivers/devicecontrol/tank0207_control.c.s
.PHONY : drivers/devicecontrol/tank0207_control.s
# target to generate assembly for a file
drivers/devicecontrol/tank0207_control.c.s:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/devicecontrol/tank0207_control.c.s
.PHONY : drivers/devicecontrol/tank0207_control.c.s
drivers/devicecontrol/tank_common.o: drivers/devicecontrol/tank_common.c.o drivers/devicecontrol/tank_common.o: drivers/devicecontrol/tank_common.c.o
.PHONY : drivers/devicecontrol/tank_common.o .PHONY : drivers/devicecontrol/tank_common.o
...@@ -1997,6 +2021,9 @@ help: ...@@ -1997,6 +2021,9 @@ help:
@echo "... drivers/devicecontrol/tank0206_control.o" @echo "... drivers/devicecontrol/tank0206_control.o"
@echo "... drivers/devicecontrol/tank0206_control.i" @echo "... drivers/devicecontrol/tank0206_control.i"
@echo "... drivers/devicecontrol/tank0206_control.s" @echo "... drivers/devicecontrol/tank0206_control.s"
@echo "... drivers/devicecontrol/tank0207_control.o"
@echo "... drivers/devicecontrol/tank0207_control.i"
@echo "... drivers/devicecontrol/tank0207_control.s"
@echo "... drivers/devicecontrol/tank_common.o" @echo "... drivers/devicecontrol/tank_common.o"
@echo "... drivers/devicecontrol/tank_common.i" @echo "... drivers/devicecontrol/tank_common.i"
@echo "... drivers/devicecontrol/tank_common.s" @echo "... drivers/devicecontrol/tank_common.s"
......
No preview for this file type
CMAKE_PROGRESS_1 = 93 CMAKE_PROGRESS_1 =
CMAKE_PROGRESS_2 = CMAKE_PROGRESS_2 =
CMAKE_PROGRESS_3 = 94 CMAKE_PROGRESS_3 = 94
CMAKE_PROGRESS_4 = CMAKE_PROGRESS_4 =
......
...@@ -17,8 +17,8 @@ CMAKE_PROGRESS_16 = ...@@ -17,8 +17,8 @@ CMAKE_PROGRESS_16 =
CMAKE_PROGRESS_17 = CMAKE_PROGRESS_17 =
CMAKE_PROGRESS_18 = 6 CMAKE_PROGRESS_18 = 6
CMAKE_PROGRESS_19 = CMAKE_PROGRESS_19 =
CMAKE_PROGRESS_20 = 7 CMAKE_PROGRESS_20 =
CMAKE_PROGRESS_21 = CMAKE_PROGRESS_21 = 7
CMAKE_PROGRESS_22 = CMAKE_PROGRESS_22 =
CMAKE_PROGRESS_23 = 8 CMAKE_PROGRESS_23 = 8
CMAKE_PROGRESS_24 = CMAKE_PROGRESS_24 =
...@@ -37,8 +37,8 @@ CMAKE_PROGRESS_36 = ...@@ -37,8 +37,8 @@ CMAKE_PROGRESS_36 =
CMAKE_PROGRESS_37 = CMAKE_PROGRESS_37 =
CMAKE_PROGRESS_38 = 13 CMAKE_PROGRESS_38 = 13
CMAKE_PROGRESS_39 = CMAKE_PROGRESS_39 =
CMAKE_PROGRESS_40 = 14 CMAKE_PROGRESS_40 =
CMAKE_PROGRESS_41 = CMAKE_PROGRESS_41 = 14
CMAKE_PROGRESS_42 = CMAKE_PROGRESS_42 =
CMAKE_PROGRESS_43 = 15 CMAKE_PROGRESS_43 = 15
CMAKE_PROGRESS_44 = CMAKE_PROGRESS_44 =
......
...@@ -10,11 +10,11 @@ CMAKE_PROGRESS_9 = ...@@ -10,11 +10,11 @@ CMAKE_PROGRESS_9 =
CMAKE_PROGRESS_10 = CMAKE_PROGRESS_10 =
CMAKE_PROGRESS_11 = 19 CMAKE_PROGRESS_11 = 19
CMAKE_PROGRESS_12 = CMAKE_PROGRESS_12 =
CMAKE_PROGRESS_13 = 20 CMAKE_PROGRESS_13 =
CMAKE_PROGRESS_14 = CMAKE_PROGRESS_14 = 20
CMAKE_PROGRESS_15 = CMAKE_PROGRESS_15 =
CMAKE_PROGRESS_16 = 21 CMAKE_PROGRESS_16 =
CMAKE_PROGRESS_17 = CMAKE_PROGRESS_17 = 21
CMAKE_PROGRESS_18 = CMAKE_PROGRESS_18 =
CMAKE_PROGRESS_19 = 22 CMAKE_PROGRESS_19 = 22
CMAKE_PROGRESS_20 = CMAKE_PROGRESS_20 =
...@@ -30,11 +30,11 @@ CMAKE_PROGRESS_29 = ...@@ -30,11 +30,11 @@ CMAKE_PROGRESS_29 =
CMAKE_PROGRESS_30 = CMAKE_PROGRESS_30 =
CMAKE_PROGRESS_31 = 26 CMAKE_PROGRESS_31 = 26
CMAKE_PROGRESS_32 = CMAKE_PROGRESS_32 =
CMAKE_PROGRESS_33 = 27 CMAKE_PROGRESS_33 =
CMAKE_PROGRESS_34 = CMAKE_PROGRESS_34 = 27
CMAKE_PROGRESS_35 = CMAKE_PROGRESS_35 =
CMAKE_PROGRESS_36 = 28 CMAKE_PROGRESS_36 =
CMAKE_PROGRESS_37 = CMAKE_PROGRESS_37 = 28
CMAKE_PROGRESS_38 = CMAKE_PROGRESS_38 =
CMAKE_PROGRESS_39 = 29 CMAKE_PROGRESS_39 = 29
CMAKE_PROGRESS_40 = CMAKE_PROGRESS_40 =
......
CMAKE_PROGRESS_1 = 85 CMAKE_PROGRESS_1 = 85
CMAKE_PROGRESS_2 = CMAKE_PROGRESS_2 =
CMAKE_PROGRESS_3 = CMAKE_PROGRESS_3 = 86
CMAKE_PROGRESS_4 = 86 CMAKE_PROGRESS_4 =
CMAKE_PROGRESS_5 = CMAKE_PROGRESS_5 =
CMAKE_PROGRESS_6 = 87 CMAKE_PROGRESS_6 = 87
CMAKE_PROGRESS_7 = CMAKE_PROGRESS_7 =
......
...@@ -8,11 +8,11 @@ CMAKE_PROGRESS_7 = ...@@ -8,11 +8,11 @@ CMAKE_PROGRESS_7 =
CMAKE_PROGRESS_8 = CMAKE_PROGRESS_8 =
CMAKE_PROGRESS_9 = 57 CMAKE_PROGRESS_9 = 57
CMAKE_PROGRESS_10 = CMAKE_PROGRESS_10 =
CMAKE_PROGRESS_11 = CMAKE_PROGRESS_11 = 58
CMAKE_PROGRESS_12 = 58 CMAKE_PROGRESS_12 =
CMAKE_PROGRESS_13 = CMAKE_PROGRESS_13 =
CMAKE_PROGRESS_14 = CMAKE_PROGRESS_14 = 59
CMAKE_PROGRESS_15 = 59 CMAKE_PROGRESS_15 =
CMAKE_PROGRESS_16 = CMAKE_PROGRESS_16 =
CMAKE_PROGRESS_17 = 60 CMAKE_PROGRESS_17 = 60
CMAKE_PROGRESS_18 = CMAKE_PROGRESS_18 =
...@@ -28,11 +28,11 @@ CMAKE_PROGRESS_27 = ...@@ -28,11 +28,11 @@ CMAKE_PROGRESS_27 =
CMAKE_PROGRESS_28 = CMAKE_PROGRESS_28 =
CMAKE_PROGRESS_29 = 64 CMAKE_PROGRESS_29 = 64
CMAKE_PROGRESS_30 = CMAKE_PROGRESS_30 =
CMAKE_PROGRESS_31 = CMAKE_PROGRESS_31 = 65
CMAKE_PROGRESS_32 = 65 CMAKE_PROGRESS_32 =
CMAKE_PROGRESS_33 = CMAKE_PROGRESS_33 =
CMAKE_PROGRESS_34 = CMAKE_PROGRESS_34 = 66
CMAKE_PROGRESS_35 = 66 CMAKE_PROGRESS_35 =
CMAKE_PROGRESS_36 = CMAKE_PROGRESS_36 =
CMAKE_PROGRESS_37 = 67 CMAKE_PROGRESS_37 = 67
CMAKE_PROGRESS_38 = CMAKE_PROGRESS_38 =
...@@ -48,11 +48,11 @@ CMAKE_PROGRESS_47 = ...@@ -48,11 +48,11 @@ CMAKE_PROGRESS_47 =
CMAKE_PROGRESS_48 = CMAKE_PROGRESS_48 =
CMAKE_PROGRESS_49 = 71 CMAKE_PROGRESS_49 = 71
CMAKE_PROGRESS_50 = CMAKE_PROGRESS_50 =
CMAKE_PROGRESS_51 = CMAKE_PROGRESS_51 = 72
CMAKE_PROGRESS_52 = 72 CMAKE_PROGRESS_52 =
CMAKE_PROGRESS_53 = CMAKE_PROGRESS_53 =
CMAKE_PROGRESS_54 = CMAKE_PROGRESS_54 = 73
CMAKE_PROGRESS_55 = 73 CMAKE_PROGRESS_55 =
CMAKE_PROGRESS_56 = CMAKE_PROGRESS_56 =
CMAKE_PROGRESS_57 = 74 CMAKE_PROGRESS_57 = 74
CMAKE_PROGRESS_58 = CMAKE_PROGRESS_58 =
...@@ -68,8 +68,8 @@ CMAKE_PROGRESS_67 = ...@@ -68,8 +68,8 @@ CMAKE_PROGRESS_67 =
CMAKE_PROGRESS_68 = CMAKE_PROGRESS_68 =
CMAKE_PROGRESS_69 = 78 CMAKE_PROGRESS_69 = 78
CMAKE_PROGRESS_70 = CMAKE_PROGRESS_70 =
CMAKE_PROGRESS_71 = CMAKE_PROGRESS_71 = 79
CMAKE_PROGRESS_72 = 79 CMAKE_PROGRESS_72 =
CMAKE_PROGRESS_73 = CMAKE_PROGRESS_73 =
CMAKE_PROGRESS_74 = 80 CMAKE_PROGRESS_74 = 80
CMAKE_PROGRESS_75 = CMAKE_PROGRESS_75 =
......
...@@ -37,6 +37,10 @@ const device_didrive device_didrive_control_config_t[]={ ...@@ -37,6 +37,10 @@ const device_didrive device_didrive_control_config_t[]={
.device_didrive_control = tank0206_change .device_didrive_control = tank0206_change
}, },
{ {
.device_id = DEVICE_TANK0207,
.device_didrive_control = tank0207_change
},
{
.device_id = DEVICE_SHIP0301, .device_id = DEVICE_SHIP0301,
.device_didrive_control = ship0301_change .device_didrive_control = ship0301_change
}, },
...@@ -52,6 +56,7 @@ const device_abnormal_close_t devcontrol_config_t[]= { ...@@ -52,6 +56,7 @@ const device_abnormal_close_t devcontrol_config_t[]= {
{ {
.device_id = DEVICE_CAR0101, .device_id = DEVICE_CAR0101,
.device_abnormal_stop = car0101_middle_pwm, .device_abnormal_stop = car0101_middle_pwm,
.device_close = NULL, // TANK0206没有单独的关闭函数
.gpio_pin_pulled=pin_all_default, .gpio_pin_pulled=pin_all_default,
.gpio_pwm_pulled=pwm_all_default .gpio_pwm_pulled=pwm_all_default
}, },
...@@ -59,6 +64,7 @@ const device_abnormal_close_t devcontrol_config_t[]= { ...@@ -59,6 +64,7 @@ const device_abnormal_close_t devcontrol_config_t[]= {
{ {
.device_id = DEVICE_CAR0102, .device_id = DEVICE_CAR0102,
.device_abnormal_stop = car0102_speed_stop, .device_abnormal_stop = car0102_speed_stop,
.device_close = NULL, // TANK0206没有单独的关闭函数
.gpio_pin_pulled=pin_all_default, .gpio_pin_pulled=pin_all_default,
.gpio_pwm_pulled=pwm_all_default .gpio_pwm_pulled=pwm_all_default
}, },
...@@ -66,6 +72,7 @@ const device_abnormal_close_t devcontrol_config_t[]= { ...@@ -66,6 +72,7 @@ const device_abnormal_close_t devcontrol_config_t[]= {
{ {
.device_id = DEVICE_CAR0103, .device_id = DEVICE_CAR0103,
.device_abnormal_stop = car0103_middle, .device_abnormal_stop = car0103_middle,
.device_close = NULL, // TANK0206没有单独的关闭函数
.gpio_pin_pulled=pin_all_default, .gpio_pin_pulled=pin_all_default,
.gpio_pwm_pulled=pwm_all_default .gpio_pwm_pulled=pwm_all_default
}, },
...@@ -73,6 +80,7 @@ const device_abnormal_close_t devcontrol_config_t[]= { ...@@ -73,6 +80,7 @@ const device_abnormal_close_t devcontrol_config_t[]= {
{ {
.device_id = DEVICE_CAR0104, .device_id = DEVICE_CAR0104,
.device_abnormal_stop = car0104_stop, .device_abnormal_stop = car0104_stop,
.device_close = NULL, // TANK0206没有单独的关闭函数
.gpio_pin_pulled=pin_all_default, .gpio_pin_pulled=pin_all_default,
.gpio_pwm_pulled=pwm_all_default .gpio_pwm_pulled=pwm_all_default
}, },
...@@ -98,13 +106,21 @@ const device_abnormal_close_t devcontrol_config_t[]= { ...@@ -98,13 +106,21 @@ const device_abnormal_close_t devcontrol_config_t[]= {
.device_abnormal_stop = tank0204_stop, .device_abnormal_stop = tank0204_stop,
.device_close = tank_thread_close, .device_close = tank_thread_close,
.gpio_pin_pulled=pin_all_default, .gpio_pin_pulled=pin_all_default,
.gpio_pwm_pulled=pwm_all_default .gpio_pwm_pulled=tankpwm_default
}, },
{ {
.device_id = DEVICE_TANK0206, .device_id = DEVICE_TANK0206,
.device_abnormal_stop = tank0206_middle, .device_abnormal_stop = tank0206_middle,
.device_close = tank_thread_close, .device_close = NULL, // TANK0206没有单独的关闭函数
.gpio_pin_pulled=pin_all_default,
.gpio_pwm_pulled=pwm_all_default
},
{
.device_id = DEVICE_TANK0207,
.device_abnormal_stop = tank0207_middle,
.device_close = NULL, // TANK0206没有单独的关闭函数
.gpio_pin_pulled=pin_all_default, .gpio_pin_pulled=pin_all_default,
.gpio_pwm_pulled=pwm_all_default .gpio_pwm_pulled=pwm_all_default
}, },
...@@ -112,6 +128,7 @@ const device_abnormal_close_t devcontrol_config_t[]= { ...@@ -112,6 +128,7 @@ const device_abnormal_close_t devcontrol_config_t[]= {
{ {
.device_id = DEVICE_SHIP0301, .device_id = DEVICE_SHIP0301,
.device_abnormal_stop = ship0301_stop, .device_abnormal_stop = ship0301_stop,
.device_close = NULL, // TANK0206没有单独的关闭函数
.gpio_pin_pulled=pin_all_default, .gpio_pin_pulled=pin_all_default,
.gpio_pwm_pulled=pwm_all_default .gpio_pwm_pulled=pwm_all_default
}, },
...@@ -119,6 +136,7 @@ const device_abnormal_close_t devcontrol_config_t[]= { ...@@ -119,6 +136,7 @@ const device_abnormal_close_t devcontrol_config_t[]= {
{ {
.device_id = DEVICE_PAO_PTZ0401, .device_id = DEVICE_PAO_PTZ0401,
.device_abnormal_stop = PTZ_pwm_init, .device_abnormal_stop = PTZ_pwm_init,
.device_close = NULL, // TANK0206没有单独的关闭函数
.gpio_pin_pulled=pin_all_default, .gpio_pin_pulled=pin_all_default,
.gpio_pwm_pulled=pwm_all_default .gpio_pwm_pulled=pwm_all_default
}, },
...@@ -126,6 +144,7 @@ const device_abnormal_close_t devcontrol_config_t[]= { ...@@ -126,6 +144,7 @@ const device_abnormal_close_t devcontrol_config_t[]= {
{ {
.device_id = DEVICE_ROBOT_DOG0501, .device_id = DEVICE_ROBOT_DOG0501,
.device_abnormal_stop = car0101_middle_pwm, .device_abnormal_stop = car0101_middle_pwm,
.device_close = NULL, // TANK0206没有单独的关闭函数
.gpio_pin_pulled=pin_all_default, .gpio_pin_pulled=pin_all_default,
.gpio_pwm_pulled=pwm_all_default .gpio_pwm_pulled=pwm_all_default
}, },
...@@ -171,7 +190,10 @@ void device_end_close(int device_id) { ...@@ -171,7 +190,10 @@ void device_end_close(int device_id) {
return; return;
} }
if(config->device_close != NULL) {
my_zlog_info("Calling device_close for ID %d", device_id);
config->device_close(); config->device_close();
}
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "tank0203_control.h" #include "tank0203_control.h"
#include "tank0204_control.h" #include "tank0204_control.h"
#include "tank0206_control.h" #include "tank0206_control.h"
#include "tank0207_control.h"
#include "ship0301_control.h" #include "ship0301_control.h"
#include "pg0403_serial.h" #include "pg0403_serial.h"
#include "tank_common.h" #include "tank_common.h"
...@@ -26,6 +27,7 @@ ...@@ -26,6 +27,7 @@
#define DEVICE_TANK0203 203 //M1A2美国坦克 #define DEVICE_TANK0203 203 //M1A2美国坦克
#define DEVICE_TANK0204 204 //美卡隆坦克 #define DEVICE_TANK0204 204 //美卡隆坦克
#define DEVICE_TANK0206 206 //可以喷水坦克 #define DEVICE_TANK0206 206 //可以喷水坦克
#define DEVICE_TANK0207 207 //可以发射水弹坦克
#define DEVICE_SHIP0301 301 // 32号船 #define DEVICE_SHIP0301 301 // 32号船
#define DEVICE_PAO_PTZ0401 401 //云台 #define DEVICE_PAO_PTZ0401 401 //云台
#define DEVICE_PG_GPS0403 403 //定位设备 #define DEVICE_PG_GPS0403 403 //定位设备
......
...@@ -89,6 +89,8 @@ int serial_open(SerialPort *sp, const char *port_name, int baud_rate) { ...@@ -89,6 +89,8 @@ int serial_open(SerialPort *sp, const char *port_name, int baud_rate) {
sp->port_name, strerror(errno)); sp->port_name, strerror(errno));
return 0; // 失败 return 0; // 失败
} }
// 方法1:保持非阻塞标志
//fcntl(sp->fd, F_SETFL, O_NONBLOCK);
// 恢复为阻塞模式(对应原代码中的 fcntl(fd_, F_SETFL, 0)) // 恢复为阻塞模式(对应原代码中的 fcntl(fd_, F_SETFL, 0))
fcntl(sp->fd, F_SETFL, 0); fcntl(sp->fd, F_SETFL, 0);
...@@ -230,27 +232,29 @@ void process_serial_data(const uint8_t *buffer, int len) { ...@@ -230,27 +232,29 @@ void process_serial_data(const uint8_t *buffer, int len) {
uint16_t raw_y = ((uint16_t)buffer[15] << 8) | buffer[16]; uint16_t raw_y = ((uint16_t)buffer[15] << 8) | buffer[16];
// 3. 执行卡尔曼滤波 x_local[i] = raw_x; // +0.5 为了四舍五入
if (g_filters[i].initialized == 0) {
// 如果是第一次收到这个标签的数据,直接初始化为测量值
// 否则滤波需要很长时间才能从 0 爬升到 实际坐标
g_filters[i].kx.estimate = (float)raw_x;
g_filters[i].ky.estimate = (float)raw_y;
g_filters[i].kx.error_cov = 1.0f;
g_filters[i].ky.error_cov = 1.0f;
g_filters[i].initialized = 1;
x_local[i] = raw_x;
y_local[i] = raw_y; y_local[i] = raw_y;
} else { // // 3. 执行卡尔曼滤波
// 后续数据进入滤波逻辑 // if (g_filters[i].initialized == 0) {
float filtered_x = run_kalman(&g_filters[i].kx, (float)raw_x); // // 如果是第一次收到这个标签的数据,直接初始化为测量值
float filtered_y = run_kalman(&g_filters[i].ky, (float)raw_y); // // 否则滤波需要很长时间才能从 0 爬升到 实际坐标
// g_filters[i].kx.estimate = (float)raw_x;
// 4. 将滤波结果转回整数存入全局变量 // g_filters[i].ky.estimate = (float)raw_y;
x_local[i] = (uint16_t)(filtered_x + 0.5f); // +0.5 为了四舍五入 // g_filters[i].kx.error_cov = 1.0f;
y_local[i] = (uint16_t)(filtered_y + 0.5f); // g_filters[i].ky.error_cov = 1.0f;
} // g_filters[i].initialized = 1;
// x_local[i] = raw_x;
// y_local[i] = raw_y;
// } else {
// // 后续数据进入滤波逻辑
// float filtered_x = run_kalman(&g_filters[i].kx, (float)raw_x);
// float filtered_y = run_kalman(&g_filters[i].ky, (float)raw_y);
// // 4. 将滤波结果转回整数存入全局变量
// x_local[i] = (uint16_t)(filtered_x + 0.5f); // +0.5 为了四舍五入
// y_local[i] = (uint16_t)(filtered_y + 0.5f);
// }
tag_id[i]=i; tag_id[i]=i;
//my_zlog_debug("串口数据更新 -> 标签ID: %d, X: %d, Y: %d", tag_id[i], x_local[i], y_local[i]); //my_zlog_debug("串口数据更新 -> 标签ID: %d, X: %d, Y: %d", tag_id[i], x_local[i], y_local[i]);
...@@ -271,7 +275,7 @@ int pg0403_serial_init_close(){ ...@@ -271,7 +275,7 @@ int pg0403_serial_init_close(){
// 新增:构建并处理 JSON 数据的函数 // 新增:构建并处理 JSON 数据的函数
// ========================================== // ==========================================
void pg0403_serial_gpssend_mqtt_json(int id, uint16_t x, uint16_t y) { void pg0403_serial_gpssend_mqtt_json(int id, uint16_t x, uint16_t y) {
// 1. 创建 JSON 对象: { }
cJSON *root = cJSON_CreateObject(); cJSON *root = cJSON_CreateObject();
if (root == NULL) { if (root == NULL) {
return; return;
...@@ -281,23 +285,15 @@ void pg0403_serial_gpssend_mqtt_json(int id, uint16_t x, uint16_t y) { ...@@ -281,23 +285,15 @@ void pg0403_serial_gpssend_mqtt_json(int id, uint16_t x, uint16_t y) {
cJSON_AddNumberToObject(head, "message_type", 1); cJSON_AddNumberToObject(head, "message_type", 1);
// 2. 向对象添加字段 cJSON_AddNumberToObject(body, "id", id);
// 这里的键名 ("tag_id", "x", "y") 可以根据你的 MQTT 协议需求修改 cJSON_AddNumberToObject(body, "resX", x);
cJSON_AddNumberToObject(body, "tag_id", id); cJSON_AddNumberToObject(body, "resY", y);
cJSON_AddNumberToObject(body, "x", x);
cJSON_AddNumberToObject(body, "y", y);
cJSON_AddItemToObject(root, "body", body); cJSON_AddItemToObject(root, "body", body);
cJSON_AddItemToObject(root, "head",head); cJSON_AddItemToObject(root, "head",head);
// 可选:添加时间戳
// cJSON_AddNumberToObject(root, "timestamp", current_timestamp_ms());
// 3. 将 JSON 对象打印为字符串
// cJSON_Print: 带缩进格式化(方便调试看)
// cJSON_PrintUnformatted: 压缩成一行(节省流量,适合 MQTT 发送)
char *json_str = cJSON_PrintUnformatted(root); char *json_str = cJSON_PrintUnformatted(root);
if (json_str == NULL) { if (json_str == NULL) {
...@@ -305,16 +301,8 @@ void pg0403_serial_gpssend_mqtt_json(int id, uint16_t x, uint16_t y) { ...@@ -305,16 +301,8 @@ void pg0403_serial_gpssend_mqtt_json(int id, uint16_t x, uint16_t y) {
return; return;
} }
// -----------------------------------------------------
// TODO: 在这里调用你的 MQTT 发送函数
// mqtt_publish("topic/location", json_str);
// -----------------------------------------------------
my_zlog_info("[MQTT Payload]: %s", json_str); my_zlog_info("[MQTT Payload]: %s", json_str);
// 4. 重要:释放内存!
// cJSON_Print 分配了 json_str 的内存,必须 free
// cJSON_CreateObject 分配了 root 的内存,必须 cJSON_Delete
char mqtt_topic_pg[256]; char mqtt_topic_pg[256];
sprintf(mqtt_topic_pg,"positioning/%s",mqtt_topic_pure_number()); sprintf(mqtt_topic_pg,"positioning/%s",mqtt_topic_pure_number());
......
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
// 卡尔曼参数配置 (根据实际效果调整) // 卡尔曼参数配置 (根据实际效果调整)
// R (测量噪声): 值越大,滤波越平滑,但滞后越明显。防止漂移建议设大一点 (10 ~ 100) // R (测量噪声): 值越大,滤波越平滑,但滞后越明显。防止漂移建议设大一点 (10 ~ 100)
// Q (过程噪声): 值越大,系统认为物体运动越快。如果对运动响应太慢,把这个调大 (0.01 ~ 1.0) // Q (过程噪声): 值越大,系统认为物体运动越快。如果对运动响应太慢,把这个调大 (0.01 ~ 1.0)
#define KALMAN_R 50.0f #define KALMAN_R 0.01f
#define KALMAN_Q 0.1f #define KALMAN_Q 0.01f
// 定义一个结构体来模拟简单的对象上下文(可选,为了保持整洁) // 定义一个结构体表示串口,整洁
typedef struct { typedef struct {
int fd; int fd;
char port_name[64]; char port_name[64];
......
...@@ -75,6 +75,9 @@ void mode_back(unsigned char gval) { ...@@ -75,6 +75,9 @@ void mode_back(unsigned char gval) {
int tank0202_change_grading(int mode){ int tank0202_change_grading(int mode){
int mode_val=0; int mode_val=0;
switch(mode){ switch(mode){
case 0:
mode_val=0;
break;
case 2: case 2:
mode_val=10; mode_val=10;
break; break;
...@@ -88,6 +91,7 @@ int tank0202_change_grading(int mode){ ...@@ -88,6 +91,7 @@ int tank0202_change_grading(int mode){
mode_val=50; mode_val=50;
break; break;
default: default:
mode_val=40;
break; break;
} }
return mode_val; return mode_val;
......
...@@ -76,6 +76,9 @@ void tank0203_mode_right_flont(unsigned char gval) { ...@@ -76,6 +76,9 @@ void tank0203_mode_right_flont(unsigned char gval) {
int tank0203_change_grading(int mode){ int tank0203_change_grading(int mode){
int mode_val=0; int mode_val=0;
switch(mode){ switch(mode){
case 0:
mode_val=0;
break;
case 2: case 2:
mode_val=10; mode_val=10;
break; break;
...@@ -89,6 +92,7 @@ int tank0203_change_grading(int mode){ ...@@ -89,6 +92,7 @@ int tank0203_change_grading(int mode){
mode_val=50; mode_val=50;
break; break;
default: default:
mode_val=30;
break; break;
} }
return mode_val; return mode_val;
......
...@@ -72,6 +72,9 @@ void tank0204_mode_back(unsigned char gval) { ...@@ -72,6 +72,9 @@ void tank0204_mode_back(unsigned char gval) {
int tank0204_change_grading(int mode){ int tank0204_change_grading(int mode){
int mode_val=0; int mode_val=0;
switch(mode){ switch(mode){
case 0:
mode_val=0;
break;
case 2: case 2:
mode_val=10; mode_val=10;
break; break;
...@@ -85,6 +88,7 @@ int tank0204_change_grading(int mode){ ...@@ -85,6 +88,7 @@ int tank0204_change_grading(int mode){
mode_val=50; mode_val=50;
break; break;
default: default:
mode_val=40;
break; break;
} }
return mode_val; return mode_val;
......
...@@ -82,6 +82,9 @@ void tank0206_mode_right_back(unsigned char gval) { ...@@ -82,6 +82,9 @@ void tank0206_mode_right_back(unsigned char gval) {
int tank0206_change_grading(int mode){ int tank0206_change_grading(int mode){
int mode_val=0; int mode_val=0;
switch(mode){ switch(mode){
case 0:
mode_val=0;
break;
case 2: case 2:
mode_val=10; mode_val=10;
break; break;
...@@ -101,6 +104,7 @@ int tank0206_change_grading(int mode){ ...@@ -101,6 +104,7 @@ int tank0206_change_grading(int mode){
mode_val=70; mode_val=70;
break; break;
default: default:
mode_val=30;
break; break;
} }
return mode_val; return mode_val;
......
#include "common.h"
#include "modules_common.h"
#include "tank0207_control.h"
#include "gpio_common.h"
void tank0207_middle() {
pwmWrite(PWM_PIN_SPEED,75);
pwmWrite(PWM_PIN_CHANGE,75);
}
void tank0207_mode_lift_flont(unsigned char gval) {
int b=0;
if (gval < 50) {
pwmWrite(PWM_PIN_SPEED, 75);
}
else if (gval <= 60) {
pwmWrite(PWM_PIN_SPEED, 80);
}else if (gval <= 90) {
pwmWrite(PWM_PIN_SPEED, 79);
}else if (gval <= 100) {
pwmWrite(PWM_PIN_SPEED, 79);
}else if(gval >100){
int flont_speed = 80+(gval-70)/10+b;
if(flont_speed>95) flont_speed = 95;
pwmWrite(PWM_PIN_SPEED, flont_speed);
}
}
void tank0207_mode_lift_back(unsigned char gval) {
int b=0;
if (gval < 50) {
pwmWrite(PWM_PIN_SPEED, 75);
} else if (gval <= 60) {
pwmWrite(PWM_PIN_SPEED, 70);
}else if (gval <= 90) {
pwmWrite(PWM_PIN_SPEED, 71);
}else if (gval <= 100) {
pwmWrite(PWM_PIN_SPEED, 71);
} else if(gval >100){
int back_speed = 71 - (gval-70)/10-b;
if(back_speed<55) back_speed =55;
pwmWrite(PWM_PIN_SPEED, back_speed);
}
}
void tank0207_mode_right_flont(unsigned char gval) {
int b=0;
if (gval < 50) {
pwmWrite(PWM_PIN_CHANGE, 75);
}
else if (gval <= 60) {
pwmWrite(PWM_PIN_CHANGE, 80);
}else if (gval <= 90) {
pwmWrite(PWM_PIN_CHANGE, 79);
}else if (gval <= 100) {
pwmWrite(PWM_PIN_CHANGE, 79);
}else if(gval >100){
int flont_speed = 80+(gval-70)/10+b;
if(flont_speed>95) flont_speed = 95;
pwmWrite(PWM_PIN_CHANGE, flont_speed);
}
}
void tank0207_mode_right_back(unsigned char gval) {
int b=0;
if (gval < 50) {
pwmWrite(PWM_PIN_CHANGE, 75);
} else if (gval <= 60) {
pwmWrite(PWM_PIN_CHANGE, 70);
}else if (gval <= 90) {
pwmWrite(PWM_PIN_CHANGE, 71);
}else if (gval <= 100) {
pwmWrite(PWM_PIN_CHANGE, 71);
} else if(gval >100){
int back_speed = 71 - (gval-70)/10-b;
if(back_speed<55) back_speed =55;
pwmWrite(PWM_PIN_CHANGE, back_speed);
}
}
int tank0207_change_grading(int mode){
int mode_val=0;
switch(mode){
case 0:
mode_val=0;
break;
case 2:
mode_val=10;
break;
case 3:
mode_val=20;
break;
case 4:
mode_val=30;
break;
case 5:
mode_val=50;
break;
case 6:
mode_val=60;
break;
case 7:
mode_val=70;
break;
default:
mode_val=40;
break;
}
return mode_val;
}
void tank0207_change(unsigned char *buf) {
unsigned char type = buf[0];
unsigned char mode = buf[1];
unsigned char val = buf[2];
static int tank0207_steering_t=0;
static int tank0207_front_t =0;
static int tank0207_front_val=0;
static int tank0207_steering_val=0;
int tank0206_count=40;
if(type != 1) tank0206_count=tank0207_change_grading(type);
if((mode == 1 ||mode == 2)&&val == 0) tank0207_front_t =0;
if((mode == 3 ||mode == 4)&&val == 0) tank0207_steering_t=0;
if(mode == 1&&val != 0) {
tank0207_front_val=val;
tank0207_front_t =1;
}else if(mode == 2&&val != 0) {
tank0207_front_t =2;
tank0207_front_val=val;
}
if(mode == 3&&val != 0) {
tank0207_steering_t =1;
tank0207_steering_val = val;
}else if(mode == 4&&val != 0) {
tank0207_steering_t =2;
tank0207_steering_val = val;
}
if(tank0207_front_t ==0&&tank0207_steering_t==0){
tank0207_mode_lift_flont(0);
tank0207_mode_right_flont(0);
}else if(tank0207_front_t ==1&&tank0207_steering_t==0){
tank0207_mode_lift_flont(tank0207_front_val);
tank0207_mode_right_flont(tank0207_front_val);
}else if(tank0207_front_t ==2&&tank0207_steering_t==0){
tank0207_mode_lift_back(tank0207_front_val);
tank0207_mode_right_back(tank0207_front_val);
}else if(tank0207_front_t ==0&&tank0207_steering_t==1){
tank0207_mode_right_flont(tank0207_steering_val+tank0206_count);
tank0207_mode_lift_back(tank0207_steering_val+tank0206_count);
}else if(tank0207_front_t ==0&&tank0207_steering_t==2){
tank0207_mode_lift_flont(tank0207_steering_val+tank0206_count);
tank0207_mode_right_back(tank0207_steering_val+tank0206_count);
}
else if(tank0207_front_t ==1&&tank0207_steering_t==1){
tank0207_mode_lift_flont(0);
tank0207_mode_right_flont(tank0207_steering_val+tank0206_count);
}else if(tank0207_front_t ==1&&tank0207_steering_t==2){
tank0207_mode_lift_flont(tank0207_steering_val+tank0206_count);
tank0207_mode_right_flont(0);
}else if(tank0207_front_t ==2&&tank0207_steering_t==1){
tank0207_mode_lift_back(0);
tank0207_mode_right_back(tank0207_steering_val+tank0206_count);
}else if(tank0207_front_t ==2&&tank0207_steering_t==2){
tank0207_mode_lift_back(tank0207_steering_val+tank0206_count);
tank0207_mode_right_back(0);
}
}
#ifndef TANK0207_CONTROL_H__
#define TANK0207_CONTROL_H__
void tank0207_middle();
void tank0207_change(unsigned char *buf);
#endif
\ No newline at end of file
...@@ -8,7 +8,7 @@ int tank_shot_back_stop(unsigned char pin,unsigned char val); ...@@ -8,7 +8,7 @@ int tank_shot_back_stop(unsigned char pin,unsigned char val);
const tank_common_back *g_tank_common_config_t = NULL; const tank_common_back *g_tank_common_config_t = NULL;
int g_tank_shot_index=0;//状态机,用于状态机,坦克接收射击倒退状态机全局变量 int g_tank_shot_index=0;//状态机,用于状态机,坦克接收射击倒退状态机全局变量
int g_tank_shot_index_cool=1;//状态机,用于冷却状态机,坦克接收射击倒退状态机全局变量 static bool s_tank_shot_index_cool=1;//状态机,用于冷却状态机,坦克接收射击倒退状态机全局变量
/*击打后退速度设置,混空模式下为单路,单独模式下为双路控制,后续需要优化*/ /*击打后退速度设置,混空模式下为单路,单独模式下为双路控制,后续需要优化*/
void tank_shot_back(unsigned char gval) { void tank_shot_back(unsigned char gval) {
...@@ -50,45 +50,134 @@ const tank_common_back tank_common_config_t[]={ ...@@ -50,45 +50,134 @@ const tank_common_back tank_common_config_t[]={
{ .device_id = -1 } { .device_id = -1 }
}; };
//多线程处理坦克发射后退线程池 static bool s_back_status=false;
void tank_shot_back_stop_task_function(void *arg) { static bool s_backshot_status=false;
if(arg!= NULL){ /*获取后退状态*/
free(arg); bool get_backstatus(){
} return s_back_status;
}
// 设置 GPIO 23 为输入模式,启用内部上拉电阻
// pinMode(23, INPUT);
// pullUpDnControl(23, PUD_UP);
// my_zlog_debug("开始监测 GPIO 23 状态...\n");
while(1){ /*获取是否在射击,射击状态*/
bool get_backshotstatus(){
return s_backshot_status;
}
//下面一部分为检测射击后后退 /*获取是否在射击,射击状态*/
// if(digitalRead(27)==LOW){ bool set_backshotstatus(bool flag){
// if(g_device_delay_back_count <= g_tank_common_config_t->back_time) { s_backshot_status=flag;
// tank_shot_back(g_tank_common_config_t->shot_back_speed); }
// my_zlog_debug("操作耗时: %lld 毫秒", interval);
// }
// }else tank_shot_back(0);
static int tank_delay_shot_back(){
if(g_device_delay_back_count <= g_tank_common_config_t->back_time) { if(g_device_delay_back_count <= g_tank_common_config_t->back_time) {
tank_shot_back(g_tank_common_config_t->shot_back_speed); tank_shot_back(g_tank_common_config_t->shot_back_speed);
my_zlog_debug("击打成功"); my_zlog_debug("击打成功");
} }
else if(g_device_delay_back_count > g_tank_common_config_t->back_time&&g_device_delay_back_count < (g_tank_common_config_t->back_time+30)){ else if(g_device_delay_back_count > g_tank_common_config_t->back_time&&g_device_delay_back_count < (g_tank_common_config_t->back_time+30)){
tank_shot_back(0); tank_shot_back(0);
my_zlog_debug("击打完成");
} }
else if(g_device_delay_back_count>g_tank_common_config_t->back_interval_back){ else if(g_device_delay_back_count>g_tank_common_config_t->back_interval_back){
g_tank_shot_index = 1; g_tank_shot_index = 1;
}else{ s_back_status=false;
delay_ms(1); }
}
//射击冷却检测计时变量
static bool s_cool_count_index =true;
/*用来判断有射击冷却的检测的状态获取*/
bool getshot_detection_index(){
return s_cool_count_index;
}
/*用来设置有射击冷却的检测的状态获取*/
bool setshot_detection_index(bool flag){
s_cool_count_index=flag;
}
// 坦克射击操作互斥锁
static pthread_mutex_t tankshot_detection_i2c_mutex = PTHREAD_MUTEX_INITIALIZER;
static int tankshot_detectionback_count=0;
/*flag=0时初始化冷却时间,1是计时,2是返回计时值,3是重置计时*/
int tankshot_detection_backcount(int *cool_time,int flag){
static int cool_count_init=0;
static int cool_count=0;
if(flag==0){
cool_count_init=*cool_time;
my_zlog_info("cool_count_init的值:%d",cool_count_init);
}
else if(flag==1){
pthread_mutex_lock(&tankshot_detection_i2c_mutex);
cool_count++;
if(cool_count>cool_count_init*2){
setshot_detection_index(true);
}
if(cool_count>200000) cool_count=200001;
pthread_mutex_unlock(&tankshot_detection_i2c_mutex);
}else if(flag==2){
return cool_count;
}else if(flag==3){
pthread_mutex_lock(&tankshot_detection_i2c_mutex);
cool_count=0;
tankshot_detectionback_count=0;
my_zlog_info("冷却计时重置");
pthread_mutex_unlock(&tankshot_detection_i2c_mutex);
}else if(flag==4){
tankshot_detectionback_count=0;
}
}
static void tankshot_detectionback(){
static bool index=0;
if(digitalRead(12)==LOW) {
s_back_status=true;
index=1;
g_device_delay_back_count=0;
delay_ms(100); // 延时 100ms,防止抖动
softPwmWrite(27, 0);
set_backshotstatus(false);
my_zlog_info("检测引脚12拉低");
} }
if(s_back_status==true&&index==1) tank_delay_shot_back();
tankshot_detectionback_count++;
if(tankshot_detectionback_count>3000){
softPwmWrite(27, 0);
}
}
//多线程处理坦克发射后退线程池
void tank_shot_back_stop_task_function(void *arg) {
if(arg!= NULL){
free(arg);
}
// 设置 GPIO 23 为输入模式,启用内部上拉电阻
// pinMode(23, INPUT);
// pullUpDnControl(23, PUD_UP);
// my_zlog_debug("开始监测 GPIO 23 状态...\n");
delay_ms(10); while(1){
switch(g_device_type){
case DEVICE_TANK0202:
case DEVICE_TANK0203:
tank_delay_shot_back();
break;
case DEVICE_TANK0204:
tankshot_detection_backcount(0,1);
tankshot_detectionback();
break;
default:
break;
} }
delay_us(500);
}
free(arg);
} }
ThreadPool_t *pool_tank_t;//坦克后退线程函数 ThreadPool_t *pool_tank_t;//坦克后退线程函数
...@@ -99,7 +188,7 @@ void tank_shot_pthrpoll_task_init(){ ...@@ -99,7 +188,7 @@ void tank_shot_pthrpoll_task_init(){
*arg = 1; *arg = 1;
pool_tank_t=thread_pool_init(1,1); pool_tank_t=thread_pool_init(1,1);
thread_pool_add_task(pool_tank_t, tank_shot_back_stop_task_function, arg); thread_pool_add_task(pool_tank_t, tank_shot_back_stop_task_function, arg);
my_zlog_debug("线程池打开"); my_zlog_info("线程池打开");
} }
/*坦克后退射击*/ /*坦克后退射击*/
...@@ -116,17 +205,23 @@ int tank_shot_back_stop(unsigned char pin,unsigned char val){ ...@@ -116,17 +205,23 @@ int tank_shot_back_stop(unsigned char pin,unsigned char val){
if(val != 0) { if(val != 0) {
if(g_tank_shot_index == 0){ if(g_tank_shot_index == 0){
tank_shot_pthrpoll_task_init(); tank_shot_pthrpoll_task_init();
g_tank_shot_index=1; g_tank_shot_index=1;
} }
if(g_tank_shot_index == 1 && g_tank_shot_index_cool==0){ if(g_tank_shot_index == 1 && s_tank_shot_index_cool==0){
g_device_delay_back_count =0; g_device_delay_back_count =0;
g_tank_shot_index = 2; g_tank_shot_index = 2;
g_tank_shot_index_cool=1; s_tank_shot_index_cool=1;
} }
} }
} }
/*设置s_tank_shot_index_cool,将他置0,让坦克后退*/
void set_tank_shot_index_cool(bool index){
s_tank_shot_index_cool=index;
}
/* /*
* @brief 销毁坦克使用的线程池,让其正常销毁,只有在tank相关设备号下才有用,最后销毁都会到device——common.h中 * @brief 销毁坦克使用的线程池,让其正常销毁,只有在tank相关设备号下才有用,最后销毁都会到device——common.h中
*/ */
......
...@@ -11,12 +11,36 @@ typedef struct { ...@@ -11,12 +11,36 @@ typedef struct {
int(*shot_back)(unsigned char pin,unsigned char val); int(*shot_back)(unsigned char pin,unsigned char val);
} tank_common_back; } tank_common_back;
typedef enum {
shot,
shot_stop
}shot_state;
/*坦克射击接口,只有在特定设备号下使用*/ /*坦克射击接口,只有在特定设备号下使用*/
void tank_shot_stop_control(int device_id,unsigned char pin,unsigned char val); void tank_shot_stop_control(int device_id,unsigned char pin,unsigned char val);
/*设置后退的时间重置s*/
void set_tank_shot_index_cool(bool index);
/*获取后退状态*/
bool get_backstatus();
/*用来判断有射击冷却的检测的状态获取*/
bool getshot_detection_index();
/*用来设置有射击冷却的检测的状态获取*/
bool setshot_detection_index(bool flag);
/*获取是否在射击,射击状态*/
bool get_backshotstatus();
/*获取是否在射击,射击状态*/
bool set_backshotstatus(bool flag);
/*检测的冷却时间,flag=0时初始化冷却时间,2是计时,3是返回计时值*/
int tankshot_detection_backcount(int *cool_time,int flag);
/*关闭线程*/ /*关闭线程*/
void tank_thread_close(); void tank_thread_close();
extern int g_tank_shot_index_cool;
#endif #endif
\ No newline at end of file
...@@ -58,7 +58,7 @@ const deviceconfig_t device_configs[] = { ...@@ -58,7 +58,7 @@ const deviceconfig_t device_configs[] = {
.device_name = "tank0202", .device_name = "tank0202",
.gpio_pins = {6, 16, 20, 22,-1},/* 补充GPIO引脚 */ .gpio_pins = {6, 16, 20, 22,-1},/* 补充GPIO引脚 */
.gpio_pwms = {5 , 7 ,24,26, 27,-1}, .gpio_pwms = {5 , 7 ,24,26, 27,-1},
.gpio_inputs={-1}, .gpio_inputs={12,-1},
.device_pwm_init = physics_pwm_init, .device_pwm_init = physics_pwm_init,
.device_control_stop = tank0202_middle,/* 补充速度控制函数 */ .device_control_stop = tank0202_middle,/* 补充速度控制函数 */
.emergency_code = 202 .emergency_code = 202
...@@ -68,7 +68,7 @@ const deviceconfig_t device_configs[] = { ...@@ -68,7 +68,7 @@ const deviceconfig_t device_configs[] = {
.device_name = "tank0203", .device_name = "tank0203",
.gpio_pins = {6, 16, 20, 22,-1},/* 补充GPIO引脚 */ .gpio_pins = {6, 16, 20, 22,-1},/* 补充GPIO引脚 */
.gpio_pwms = {5 , 7 ,24, 26, 27,-1}, .gpio_pwms = {5 , 7 ,24, 26, 27,-1},
.gpio_inputs={-1}, .gpio_inputs={12,-1},
.device_pwm_init = physics_pwm_init, .device_pwm_init = physics_pwm_init,
.device_control_stop = tank0203_middle,/* 补充速度控制函数 */ .device_control_stop = tank0203_middle,/* 补充速度控制函数 */
.emergency_code = 203 .emergency_code = 203
...@@ -78,7 +78,7 @@ const deviceconfig_t device_configs[] = { ...@@ -78,7 +78,7 @@ const deviceconfig_t device_configs[] = {
.device_name = "tank0204", .device_name = "tank0204",
.gpio_pins = {6, 16, 20, 22,-1},/* 补充GPIO引脚 */ .gpio_pins = {6, 16, 20, 22,-1},/* 补充GPIO引脚 */
.gpio_pwms = {5 , 7 ,24, 26, 27,-1}, .gpio_pwms = {5 , 7 ,24, 26, 27,-1},
.gpio_inputs={-1}, .gpio_inputs={12,-1},
.device_pwm_init = physics_pwm_init, .device_pwm_init = physics_pwm_init,
.device_control_stop = tank0204_stop,/* 补充速度控制函数 */ .device_control_stop = tank0204_stop,/* 补充速度控制函数 */
.emergency_code = 204 .emergency_code = 204
...@@ -94,6 +94,16 @@ const deviceconfig_t device_configs[] = { ...@@ -94,6 +94,16 @@ const deviceconfig_t device_configs[] = {
.emergency_code = 206 .emergency_code = 206
}, },
{ {
.device_id = DEVICE_TANK0207,
.device_name = "tank0207",
.gpio_pins = {6, 16, 20, 22, 23,-1},/* 补充GPIO引脚 */
.gpio_pwms = {5 , 7 ,24,26, 27,-1},
.gpio_inputs={-1},
.device_pwm_init = physics_pwm_init,
.device_control_stop = tank0207_middle,/* 补充速度控制函数 */
.emergency_code = 207
},
{
.device_id = DEVICE_SHIP0301, .device_id = DEVICE_SHIP0301,
.device_name = "ship0301", .device_name = "ship0301",
.gpio_pins = {6, 16, 20, 22, 23,-1},/* 补充GPIO引脚 */ .gpio_pins = {6, 16, 20, 22, 23,-1},/* 补充GPIO引脚 */
......
...@@ -5,10 +5,11 @@ ...@@ -5,10 +5,11 @@
#include "gpio_control.h" #include "gpio_control.h"
#define GPIO_ID_THREAD_COUNT 3 #define GPIO_ID_THREAD_COUNT 3
#define GPIO_ID_SHOT_ONLYCOOL_COUNT 4 //仅需要打开射击冷却的设备数量 #define GPIO_ID_SHOT_ONLYCOOL_COUNT 5 //仅需要打开射击冷却的设备数量
int gpio_device_id[GPIO_ID_THREAD_COUNT]={DEVICE_TANK0202,DEVICE_TANK0203,DEVICE_TANK0204};//需要打开线程池设备号 static int gpio_device_id[GPIO_ID_THREAD_COUNT]={DEVICE_TANK0202,DEVICE_TANK0203,DEVICE_TANK0204};//需要打开线程池设备号
int gpio_device_cool_id[GPIO_ID_SHOT_ONLYCOOL_COUNT]={DEVICE_TANK0202,DEVICE_TANK0203,DEVICE_TANK0204,DEVICE_TANK0206};//仅需要打开射击冷却的设备号 static int gpio_device_cool_id[GPIO_ID_SHOT_ONLYCOOL_COUNT]={DEVICE_TANK0202,DEVICE_TANK0203,DEVICE_TANK0204,DEVICE_TANK0206
,DEVICE_TANK0207};//仅需要打开射击冷却的设备号
const gpiocontrol_t *gpio_control_config_t = NULL ;//gpio结构体标识 const gpiocontrol_t *gpio_control_config_t = NULL ;//gpio结构体标识
...@@ -24,6 +25,7 @@ void tank0202_pwm_value(int pin,int value); ...@@ -24,6 +25,7 @@ void tank0202_pwm_value(int pin,int value);
void tank0203_pwm_value(int pin,int value); void tank0203_pwm_value(int pin,int value);
void tank0204_pwm_value(int pin,int value); void tank0204_pwm_value(int pin,int value);
void tank0206_pwm_value(int pin,int value); void tank0206_pwm_value(int pin,int value);
void tank0207_pwm_value(int pin,int value);
void ship0301_pwm_value(int pin,int value); void ship0301_pwm_value(int pin,int value);
void dog0501_pwm_value(int pin,int value); void dog0501_pwm_value(int pin,int value);
...@@ -42,6 +44,19 @@ void device_shot_fire_init(TankFireControl* this) { ...@@ -42,6 +44,19 @@ void device_shot_fire_init(TankFireControl* this) {
this->state = TANK_STATE_READY; this->state = TANK_STATE_READY;
this->shot_interval_ms = 1000; this->shot_interval_ms = 1000;
this->shot_duration_ms = 1000; this->shot_duration_ms = 1000;
}else if(g_device_type==DEVICE_TANK0207){
this->last_shot_end_time = 0;
this->shooting_start_time = 0;
this->state = TANK_STATE_READY;
this->shot_interval_ms = 1000;
this->shot_duration_ms = 1000;
}else if(g_device_type==DEVICE_TANK0204){
this->last_shot_end_time = 0;
this->shooting_start_time = 0;
this->state = TANK_STATE_READY;
this->shot_interval_ms = 5000;
this->shot_duration_ms = 1500;
tankshot_detection_backcount(&this->shot_interval_ms,0);
}else{ }else{
this->last_shot_end_time = 0; this->last_shot_end_time = 0;
this->shooting_start_time = 0; this->shooting_start_time = 0;
...@@ -50,6 +65,7 @@ void device_shot_fire_init(TankFireControl* this) { ...@@ -50,6 +65,7 @@ void device_shot_fire_init(TankFireControl* this) {
this->shot_duration_ms = 1000; this->shot_duration_ms = 1000;
} }
} }
/* /*
...@@ -71,6 +87,7 @@ int device_shot_cooling_init(){ ...@@ -71,6 +87,7 @@ int device_shot_cooling_init(){
* @brief 检查射击状态 * @brief 检查射击状态
* @param this 控制器指针 * @param this 控制器指针
* @return 0=允许射击, -1=禁止射击(冷却中或射击中) * @return 0=允许射击, -1=禁止射击(冷却中或射击中)
* 此为延时冷却,以时间为主
*/ */
int device_fire_check(TankFireControl* this) { int device_fire_check(TankFireControl* this) {
uint64_t current_time = get_current_time_millis(); uint64_t current_time = get_current_time_millis();
...@@ -124,7 +141,8 @@ int device_fire_check(TankFireControl* this) { ...@@ -124,7 +141,8 @@ int device_fire_check(TankFireControl* this) {
this->last_shot_end_time = current_time; this->last_shot_end_time = current_time;
this->state = TANK_STATE_COOLDOWN; this->state = TANK_STATE_COOLDOWN;
g_tank_shot_index_cool = 0;
set_tank_shot_index_cool(0);//当为0坦克才能进入发炮完后退时间重置
return -1; // 射击刚刚结束 return -1; // 射击刚刚结束
} }
...@@ -239,6 +257,12 @@ const gpiocontrol_t gpio_configs[] = { ...@@ -239,6 +257,12 @@ const gpiocontrol_t gpio_configs[] = {
.device_pwm_value =tank0206_pwm_value .device_pwm_value =tank0206_pwm_value
}, },
{ {
.device_id = DEVICE_TANK0207,
.category_id=WATER_TANK,
.device_pin_value =public_pin_value,
.device_pwm_value =tank0207_pwm_value
},
{
.device_id = DEVICE_SHIP0301, .device_id = DEVICE_SHIP0301,
.category_id=WATER_SHIP, .category_id=WATER_SHIP,
.device_pin_value =public_pin_value, .device_pin_value =public_pin_value,
...@@ -457,6 +481,17 @@ void public_pwm_value(int pin ,int value){ ...@@ -457,6 +481,17 @@ void public_pwm_value(int pin ,int value){
} }
/*引脚复用检查,26引脚检查,只有使用的需要*/
int devicegpio_pwmreuse(int pin,int value,int val){
if(pin==26&&value==1){
tankshot_detection_backcount(NULL,4);
softPwmWrite(27, val);
}
if(pin==26&&value==0){
softPwmWrite(27, val);
}
}
void tank0202_pwm_value(int pin,int value) { //软件陪我们控制调速 void tank0202_pwm_value(int pin,int value) { //软件陪我们控制调速
for(int i = 0 ; i <= g_gpio_softpwmcount ; i++) { for(int i = 0 ; i <= g_gpio_softpwmcount ; i++) {
if(pin == g_gpioPwm[i]) { if(pin == g_gpioPwm[i]) {
...@@ -472,6 +507,7 @@ void tank0202_pwm_value(int pin,int value) { //软件陪我们控制调速 ...@@ -472,6 +507,7 @@ void tank0202_pwm_value(int pin,int value) { //软件陪我们控制调速
device_shoting_check(27,30); device_shoting_check(27,30);
} else { } else {
softPwmWrite(pin, 30); softPwmWrite(pin, 30);
devicegpio_pwmreuse(pin,value,30);
my_zlog_info("pwm:%d",pin); my_zlog_info("pwm:%d",pin);
} }
if(limit_status==LIMIT_LIFT) { if(limit_status==LIMIT_LIFT) {
...@@ -486,6 +522,7 @@ void tank0202_pwm_value(int pin,int value) { //软件陪我们控制调速 ...@@ -486,6 +522,7 @@ void tank0202_pwm_value(int pin,int value) { //软件陪我们控制调速
}else if(value==0) { }else if(value==0) {
softPwmWrite(pin, 0); softPwmWrite(pin, 0);
devicegpio_pwmreuse(pin,value,0);
my_zlog_info("pwm:%d,0",pin); my_zlog_info("pwm:%d,0",pin);
} }
my_zlog_info("tank0202 pwm"); my_zlog_info("tank0202 pwm");
...@@ -506,6 +543,7 @@ void tank0203_pwm_value(int pin,int value) { //软件陪我们控制调速 ...@@ -506,6 +543,7 @@ void tank0203_pwm_value(int pin,int value) { //软件陪我们控制调速
device_shoting_check(27,30); device_shoting_check(27,30);
} else { } else {
softPwmWrite(pin, 30); softPwmWrite(pin, 30);
devicegpio_pwmreuse(pin,value,30);
my_zlog_info("pwm:%d",pin); my_zlog_info("pwm:%d",pin);
} }
if(limit_status==LIMIT_LIFT) { if(limit_status==LIMIT_LIFT) {
...@@ -521,6 +559,7 @@ void tank0203_pwm_value(int pin,int value) { //软件陪我们控制调速 ...@@ -521,6 +559,7 @@ void tank0203_pwm_value(int pin,int value) { //软件陪我们控制调速
}else if(value==0) { }else if(value==0) {
softPwmWrite(pin, 0); softPwmWrite(pin, 0);
devicegpio_pwmreuse(pin,value,0);
my_zlog_info("pwm:%d,0",pin); my_zlog_info("pwm:%d,0",pin);
} }
my_zlog_info("tank0203 pwm"); my_zlog_info("tank0203 pwm");
...@@ -538,15 +577,27 @@ void tank0204_pwm_value(int pin,int value){ ...@@ -538,15 +577,27 @@ void tank0204_pwm_value(int pin,int value){
if(value==1) { if(value==1) {
if(pin == 27){ if(pin == 27){
device_shoting_check(27,30); //device_shoting_check(27,100);
if(getshot_detection_index()==true){
softPwmWrite(27, 100);
setshot_detection_index(true);
tankshot_detection_backcount(NULL,3);
set_backshotstatus(true);
my_zlog_info("冷却完成,射击开始");
}
//set_tank_shot_index_cool(0);
}else if(pin == 5) { }else if(pin == 5) {
softPwmWrite(7, 25); softPwmWrite(7, 35);
my_zlog_info("pwm:7,1"); my_zlog_info("pwm:7,1");
}else if(pin == 7) { }else if(pin == 7) {
softPwmWrite(5, 25); softPwmWrite(5, 35);
my_zlog_info("pwm:5,1"); my_zlog_info("pwm:5,1");
}else { }else {
if(pin==26&&get_backshotstatus()!=true) {
devicegpio_pwmreuse(pin,value,100);
softPwmWrite(pin, 60); softPwmWrite(pin, 60);
}
if(pin!=26)softPwmWrite(pin, 60);
my_zlog_info("pwm:%d",pin); my_zlog_info("pwm:%d",pin);
} }
...@@ -568,10 +619,16 @@ void tank0204_pwm_value(int pin,int value){ ...@@ -568,10 +619,16 @@ void tank0204_pwm_value(int pin,int value){
softPwmWrite(5, 0); softPwmWrite(5, 0);
my_zlog_info("pwm:5,0",pin); my_zlog_info("pwm:5,0",pin);
}else{ }else{
if(pin!=27) {
if(pin==26&&get_backshotstatus()!=true){
softPwmWrite(pin, 0); softPwmWrite(pin, 0);
devicegpio_pwmreuse(pin,value,0);
}
if(pin!=26)softPwmWrite(pin, 0);
my_zlog_info("pwm:%d,0",pin); my_zlog_info("pwm:%d,0",pin);
} }
} }
}
my_zlog_info("tank0204 pwm"); my_zlog_info("tank0204 pwm");
} }
...@@ -601,6 +658,32 @@ void tank0206_pwm_value(int pin,int value) { //软件陪我们控制调速 ...@@ -601,6 +658,32 @@ void tank0206_pwm_value(int pin,int value) { //软件陪我们控制调速
my_zlog_info("tank0206 pwm"); my_zlog_info("tank0206 pwm");
} }
void tank0207_pwm_value(int pin,int value) { //软件陪我们控制调速
for(int i = 0 ; i <= g_gpio_softpwmcount ; i++) {
if(pin == g_gpioPwm[i]) {
break;
}
if(i == g_gpio_softpwmcount) {
return ;
}
}
if(value==1) {
if(pin == 27){
device_shoting_check(26, 100);
} else {
softPwmWrite(pin, 35);
my_zlog_info("pwm:%d",pin);
}
}else if(value==0) {
if(pin == 27) softPwmWrite(26, 0);
softPwmWrite(pin, 0);
my_zlog_info("pwm:%d,0",pin);
}
my_zlog_info("tank0206 pwm");
}
void ship0301_pwm_value(int pin,int value) { //软件陪我们控制调速 void ship0301_pwm_value(int pin,int value) { //软件陪我们控制调速
for(int i = 0 ; i <= g_gpio_softpwmcount ; i++) { for(int i = 0 ; i <= g_gpio_softpwmcount ; i++) {
if(pin == g_gpioPwm[i]) { if(pin == g_gpioPwm[i]) {
......
...@@ -72,6 +72,15 @@ void pwm_all_default() {//全部至低电平,车和坦克共用 ...@@ -72,6 +72,15 @@ void pwm_all_default() {//全部至低电平,车和坦克共用
} }
} }
void tankpwm_default() {//全部至低电平,车和坦克共用
for (int i=0;i<g_gpio_softpwmcount;i++) {
if(g_gpioPwm[i]!=27) softPwmWrite(g_gpioPwm[i], 0);
}
}
/*物理pwm初始化*/ /*物理pwm初始化*/
void physics_pwm_init() { void physics_pwm_init() {
......
...@@ -30,5 +30,7 @@ void pin_value(int pin,int value); ...@@ -30,5 +30,7 @@ void pin_value(int pin,int value);
void physics_pwm_init(); void physics_pwm_init();
void pwm_value(int pin,int value); //软件陪我们控制调速 void pwm_value(int pin,int value); //软件陪我们控制调速
void tankpwm_default();//坦克专用pwm置0引脚
#endif #endif
...@@ -5,13 +5,15 @@ ...@@ -5,13 +5,15 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/i2c-dev.h> #include <linux/i2c-dev.h>
#include <stdint.h> #include <stdint.h>
#include <pthread.h>
#define I2C_DEVICE "/dev/i2c-2" // 示例:使用 I2C 总线 2 #define I2C_DEVICE "/dev/i2c-2" // 示例:使用 I2C 总线 2
static int fd = 0; static int fd = 0;
static uint8_t current_iic_addr = 0; // 记录当前设置的 I2C 地址 static uint8_t current_iic_addr = 0; // 记录当前设置的 I2C 地址
static pthread_mutex_t i2c_mutex = PTHREAD_MUTEX_INITIALIZER; // I2C 操作互斥锁
int hardware_iic_config_init(); int hardware_iic_config_init();
int hardware_iic_init() { int hardware_iic_init() {
...@@ -54,8 +56,14 @@ int set_hardware_iic(uint8_t iic_addr) { ...@@ -54,8 +56,14 @@ int set_hardware_iic(uint8_t iic_addr) {
// data: 要写入的数据 // data: 要写入的数据
// len: 数据长度 (不包括寄存器地址) // len: 数据长度 (不包括寄存器地址)
int hardware_iic_write(uint8_t device_addr, uint8_t reg_addr, const uint8_t *data, int len) { int hardware_iic_write(uint8_t device_addr, uint8_t reg_addr, const uint8_t *data, int len) {
// 加锁,确保同一时间只有一个线程访问 I2C
pthread_mutex_lock(&i2c_mutex);
int ret = 1; // 默认失败
do{
if (set_hardware_iic(device_addr) != 0) { if (set_hardware_iic(device_addr) != 0) {
return 1; break;
} }
// 构建发送缓冲区:第一个字节是寄存器地址,后面是数据 // 构建发送缓冲区:第一个字节是寄存器地址,后面是数据
...@@ -67,10 +75,15 @@ int hardware_iic_write(uint8_t device_addr, uint8_t reg_addr, const uint8_t *dat ...@@ -67,10 +75,15 @@ int hardware_iic_write(uint8_t device_addr, uint8_t reg_addr, const uint8_t *dat
if (write(fd, write_buf, len + 1) != (len + 1)) { if (write(fd, write_buf, len + 1) != (len + 1)) {
my_zlog_warn("错误:向设备 0x%02X 寄存器 0x%02X 写入数据失败。", device_addr, reg_addr); my_zlog_warn("错误:向设备 0x%02X 寄存器 0x%02X 写入数据失败。", device_addr, reg_addr);
return 1; break;
} }
pthread_mutex_unlock(&i2c_mutex);
ret = 0; // 成功
}while(0);
// my_zlog_info("成功向设备 0x%02X 寄存器 0x%02X 写入 %d 字节数据。", device_addr, reg_addr, len); // my_zlog_info("成功向设备 0x%02X 寄存器 0x%02X 写入 %d 字节数据。", device_addr, reg_addr, len);
return 0; return ret;
} }
// 硬件 I2C 读取函数 // 硬件 I2C 读取函数
...@@ -79,23 +92,33 @@ int hardware_iic_write(uint8_t device_addr, uint8_t reg_addr, const uint8_t *dat ...@@ -79,23 +92,33 @@ int hardware_iic_write(uint8_t device_addr, uint8_t reg_addr, const uint8_t *dat
// data: 存储读取数据的缓冲区 // data: 存储读取数据的缓冲区
// len: 要读取的数据长度 // len: 要读取的数据长度
int hardware_iic_read(uint8_t device_addr, uint8_t reg_addr, uint8_t *data, int len) { int hardware_iic_read(uint8_t device_addr, uint8_t reg_addr, uint8_t *data, int len) {
int ret=1;
pthread_mutex_lock(&i2c_mutex);
do{
if (set_hardware_iic(device_addr) != 0) { if (set_hardware_iic(device_addr) != 0) {
return 1; break;
} }
// 先写入要读取的寄存器地址 // 先写入要读取的寄存器地址
if (write(fd, &reg_addr, 1) != 1) { if (write(fd, &reg_addr, 1) != 1) {
my_zlog_warn("错误:向设备 0x%02X 设置读取寄存器 0x%02X 失败。", device_addr, reg_addr); my_zlog_warn("错误:向设备 0x%02X 设置读取寄存器 0x%02X 失败。", device_addr, reg_addr);
return 1; break;
} }
// 然后从该寄存器读取数据 // 然后从该寄存器读取数据
if (read(fd, data, len) != len) { if (read(fd, data, len) != len) {
my_zlog_warn("错误:从设备 0x%02X 寄存器 0x%02X 读取 %d 字节数据失败。", device_addr, reg_addr, len); my_zlog_warn("错误:从设备 0x%02X 寄存器 0x%02X 读取 %d 字节数据失败。", device_addr, reg_addr, len);
return 1; break;
} }
ret = 0;
}while(0);
pthread_mutex_unlock(&i2c_mutex);
// my_zlog_info("成功从设备 0x%02X 寄存器 0x%02X 读取 %d 字节数据。", device_addr, reg_addr, len); // my_zlog_info("成功从设备 0x%02X 寄存器 0x%02X 读取 %d 字节数据。", device_addr, reg_addr, len);
return 0; return ret;
} }
int hardware_iic_close() { int hardware_iic_close() {
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
#include "common.h" #include "common.h"
#include "ads1115.h" #include "ads1115.h"
double tank_angle(){ double tank_angle(){
double angle=0; double angle=0;
float angle_shot=ads1115_read_channel(2); float angle_shot=ads1115_read_channel(2);
......
...@@ -53,7 +53,7 @@ int parse_device_config(const char *json_str) { ...@@ -53,7 +53,7 @@ int parse_device_config(const char *json_str) {
if (cJSON_IsString(item)) { if (cJSON_IsString(item)) {
strncpy(g_mqtt_cam_config_t->mqtt_servers[i], item->valuestring, sizeof(g_mqtt_cam_config_t->mqtt_servers[i]) - 1); strncpy(g_mqtt_cam_config_t->mqtt_servers[i], item->valuestring, sizeof(g_mqtt_cam_config_t->mqtt_servers[i]) - 1);
g_mqtt_cam_config_t->mqtt_servers[i][sizeof(g_mqtt_cam_config_t->mqtt_servers[i]) - 1] = '\0'; g_mqtt_cam_config_t->mqtt_servers[i][sizeof(g_mqtt_cam_config_t->mqtt_servers[i]) - 1] = '\0';
my_zlog_info(" [%d] %s", i, g_mqtt_cam_config_t->mqtt_servers[i]); my_zlog_info(" [%d] %s", i+1, g_mqtt_cam_config_t->mqtt_servers[i]);
i = i + 1; i = i + 1;
} }
} }
......
...@@ -131,7 +131,6 @@ int receive_jwt(cJSON *body) { ...@@ -131,7 +131,6 @@ int receive_jwt(cJSON *body) {
my_zlog_debug("在有效期内"); my_zlog_debug("在有效期内");
pthread_mutex_lock(&g_verify_mutex); pthread_mutex_lock(&g_verify_mutex);
g_verify_count=0; g_verify_count=0;
my_zlog_info("count: %s", g_verify_count);
pthread_mutex_unlock(&g_verify_mutex); pthread_mutex_unlock(&g_verify_mutex);
my_zlog_debug("g_verify_count=%d",g_verify_count); my_zlog_debug("g_verify_count=%d",g_verify_count);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment