提交 e67101d9 authored 作者: blu's avatar blu

bug修复, 重构及ptz实现

上级 61621d77
...@@ -43,7 +43,9 @@ const string consts::kMsgCode = "code"; ...@@ -43,7 +43,9 @@ const string consts::kMsgCode = "code";
const string consts::kMsgMsg = "msg"; const string consts::kMsgMsg = "msg";
const string consts::kMsgSn = "sn"; const string consts::kMsgSn = "sn";
const string consts::recFilePath = "/mnt/sd/records/"; const string consts::recFilePath = "/mnt/sd/records/";
const long long consts::TS_2020 = 1577836800000L; const long long consts::TS_2020 = 1577836800000L; /// ms
const long long consts::TS_MAX = 9999999999999L; /// ms
/// topics /// topics
const string consts::sub_topic = "evcamera/v1.0/request/"; const string consts::sub_topic = "evcamera/v1.0/request/";
const string consts::pub_topic_response = "evcamera/v1.0/response/"; const string consts::pub_topic_response = "evcamera/v1.0/response/";
...@@ -264,17 +266,19 @@ int z_recv_multiple(void *s, vector<uint8_t> &buf, int &frames) ...@@ -264,17 +266,19 @@ int z_recv_multiple(void *s, vector<uint8_t> &buf, int &frames)
} }
namespace _internal_ { namespace _internal_ {
mutex mutConfigFiles; recursive_mutex mutConfigFiles;
} }
/// mk MUST NOT be null when isMerge is true /// mk MUST NOT be null when isMerge is true
string save_json(json &data, string path, bool isMerge, fn_mk_default_json mk) string save_json(json &data, string path, bool isMerge, fn_mk_default_json mk)
{ {
lock_guard<mutex> lk(_internal_::mutConfigFiles); lock_guard<recursive_mutex> lk(_internal_::mutConfigFiles);
string rc; string rc;
json js; json js;
if(isMerge) { if(isMerge) {
/// load configuration first
spdlog::info("save_json merge");
rc = load_json(js, path, mk); rc = load_json(js, path, mk);
if(!rc.empty()) { if(!rc.empty()) {
return rc; return rc;
...@@ -286,11 +290,12 @@ string save_json(json &data, string path, bool isMerge, fn_mk_default_json mk) ...@@ -286,11 +290,12 @@ string save_json(json &data, string path, bool isMerge, fn_mk_default_json mk)
rc = fmt::format("failed to merge json: {}, {} + {}", e.what(), js.to_string(), data.to_string()); rc = fmt::format("failed to merge json: {}, {} + {}", e.what(), js.to_string(), data.to_string());
return rc; return rc;
} }
spdlog::info("save_json merge end");
} }
ofstream ocfg_(path, std::ios::trunc); ofstream ocfg_(path, std::ios::trunc);
if(ocfg_.is_open()) { if(ocfg_.is_open()) {
ocfg_ << pretty_print(data); ocfg_ << pretty_print(js);
ocfg_.flush(); ocfg_.flush();
ocfg_.close(); ocfg_.close();
} }
...@@ -303,14 +308,14 @@ string save_json(json &data, string path, bool isMerge, fn_mk_default_json mk) ...@@ -303,14 +308,14 @@ string save_json(json &data, string path, bool isMerge, fn_mk_default_json mk)
string load_json(json &config, string path, fn_mk_default_json mk) string load_json(json &config, string path, fn_mk_default_json mk)
{ {
lock_guard<mutex> lk(_internal_::mutConfigFiles); lock_guard<recursive_mutex> lk(_internal_::mutConfigFiles);
string rc; string rc;
try { try {
ifstream cfg_(path); ifstream cfg_(path);
config = json::parse(cfg_); config = json::parse(cfg_);
} }
catch(exception &e) { catch(exception &e) {
spdlog::error("failed loading config: {}, force to make default config:\n{}", e.what(), config.to_string()); spdlog::error("failed loading config {}: {}, force to make default config:\n{}", path, e.what(), config.to_string());
if(mk != nullptr) { if(mk != nullptr) {
config = mk(); config = mk();
} }
......
...@@ -60,6 +60,7 @@ typedef struct consts{ ...@@ -60,6 +60,7 @@ typedef struct consts{
static const string recFilePath; static const string recFilePath;
static const long long TS_2020; static const long long TS_2020;
static const long long TS_MAX;
/// topics /// topics
static const string sub_topic; static const string sub_topic;
static const string pub_topic_response; static const string pub_topic_response;
...@@ -227,7 +228,7 @@ public: ...@@ -227,7 +228,7 @@ public:
}; };
typedef json(*fn_mk_default_json)(); typedef json(*fn_mk_default_json)();
extern string save_json(json &data, string path, bool isMerge, fn_mk_default_json mk = nullptr); extern string save_json(json &data, string path, bool isMerge = false, fn_mk_default_json mk = nullptr);
extern string load_json(json &config, string path, fn_mk_default_json mk = nullptr); extern string load_json(json &config, string path, fn_mk_default_json mk = nullptr);
} }
......
...@@ -740,7 +740,7 @@ void handle_mqtt_req(MqttHelper *hlp, const void * const data, int len, string t ...@@ -740,7 +740,7 @@ void handle_mqtt_req(MqttHelper *hlp, const void * const data, int len, string t
else if(cmd == consts::kMsgCmdUploadVideo) { else if(cmd == consts::kMsgCmdUploadVideo) {
// upload video // upload video
if(gRecFilesList == nullptr) { if(gRecFilesList == nullptr) {
MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, -1, "no sd card", js.contains(consts::kMsgCmd)?js[consts::kMsgCmd].as<string>():string(""), js.contains(consts::kMsgRid)?js[consts::kMsgRid].as<string>():string(""), data); MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, -1, "no sd card", cmd, rid, data);
} }
else { else {
auto tss = data["start"].as<long long>(); auto tss = data["start"].as<long long>();
...@@ -750,13 +750,30 @@ void handle_mqtt_req(MqttHelper *hlp, const void * const data, int len, string t ...@@ -750,13 +750,30 @@ void handle_mqtt_req(MqttHelper *hlp, const void * const data, int len, string t
tss = tss * 1000; tss = tss * 1000;
tse = tse * 1000; tse = tse * 1000;
} }
bool isTsValid = false;
if(tss <= tse && tss > consts::TS_2020 && tse < consts::TS_MAX){
// in ms
isTsValid = true;
}else{
tss = tss/1000;
tse = tse/1000;
if(tss <= tse && tss > consts::TS_2020/1000 && tse < consts::TS_MAX/1000 ){
// in seconds
isTsValid = true;
}
}
if(!isTsValid) {
MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, EV_MSG_ERROR_INVALID_PARAM, "time stamps errror. start <= end and both in millisecon or second format ", cmd, rid, data);
}else{
long long offsetE = 0, offsetS = 0; long long offsetE = 0, offsetS = 0;
auto res = gRecFilesList->findByRange(tss, tse, offsetS, offsetE); auto res = gRecFilesList->findByRange(tss, tse, offsetS, offsetE);
if(res.empty()) { if(res.empty()) {
MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, -2, "no video found", js.contains(consts::kMsgCmd)?js[consts::kMsgCmd].as<string>():string(""), js.contains(consts::kMsgRid)?js[consts::kMsgRid].as<string>():string(""), data); MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, -2, "no video found", cmd, rid, data);
} }
else { else {
MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, 0, "OK", js.contains(consts::consts::kMsgCmd)?js[consts::kMsgCmd].as<string>():string(""), js.contains(consts::kMsgRid)?js[consts::kMsgRid].as<string>():string(""), data); MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, 0, "OK", cmd, rid, data);
print_ts_files(*gRecFilesList); print_ts_files(*gRecFilesList);
printf("matched (%lld, %lld) with offsets %lld, %lld:\n\t", tss, tse, offsetS, offsetE); printf("matched (%lld, %lld) with offsets %lld, %lld:\n\t", tss, tse, offsetS, offsetE);
for(auto &k: res) { for(auto &k: res) {
...@@ -766,9 +783,10 @@ void handle_mqtt_req(MqttHelper *hlp, const void * const data, int len, string t ...@@ -766,9 +783,10 @@ void handle_mqtt_req(MqttHelper *hlp, const void * const data, int len, string t
} }
} }
} }
}
else if(cmd == consts::kMsgCmdGetConfig) { else if(cmd == consts::kMsgCmdGetConfig) {
// response config // response config
MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, 0, "OK", js.contains(consts::kMsgCmd)?js[consts::kMsgCmd].as<string>():string(""), js.contains(consts::kMsgRid)?js[consts::kMsgRid].as<string>():string(""), gJsonConfig); MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, 0, "OK", cmd, rid, gJsonConfig);
} }
else if(cmd == consts::kMsgCmdStatus) { else if(cmd == consts::kMsgCmdStatus) {
// response status // response status
...@@ -796,19 +814,25 @@ void handle_mqtt_req(MqttHelper *hlp, const void * const data, int len, string t ...@@ -796,19 +814,25 @@ void handle_mqtt_req(MqttHelper *hlp, const void * const data, int len, string t
} }
else if(cmd == consts::kMsgCmdPtz) { else if(cmd == consts::kMsgCmdPtz) {
// response Ptz control // response Ptz control
/// TODO: spdlog::info("mqtt got ptz cmd: {}", data.to_string());
if(!data.contains("action") || !data.contains("degree")) { if(!data.contains("action") || !data.contains("degree")) {
MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, EV_MSG_ERROR_INVALID_PARAM, "invalid param in data field", cmd, rid, data); MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, EV_MSG_ERROR_INVALID_PARAM, "invalid param in data field", cmd, rid, data);
return; }else{
} /// TODO: issue need to clear
str = ptz_move(data["action"].as<string>(), data["degree"].as<float>()); if(true){
spdlog::info("mqtt begin move");
string rc = ptz_move(data["action"].as<string>(), data["degree"].as<float>());
spdlog::info("mqtt end move");
if(!str.empty()) { if(!str.empty()) {
MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, EV_MSG_ERROR_INVALID_PARAM, str, cmd, rid, data); MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, EV_MSG_ERROR_INVALID_PARAM, rc, cmd, rid, data);
return; }else{
}
MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, 0, "OK", cmd, rid, data); MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, 0, "OK", cmd, rid, data);
} }
}else{
MqttMgr::report_response_args(gMqttClient, consts::pub_topic_response + rid, EV_MSG_ERROR_UNSUPPORTED_CMD, "there is hanging issue need to be fixed, before this command is available", cmd, rid, data);
}
}
}
else if(cmd == "list_videos") { else if(cmd == "list_videos") {
if(gRecFilesList != nullptr) if(gRecFilesList != nullptr)
print_ts_files(*gRecFilesList); print_ts_files(*gRecFilesList);
...@@ -818,8 +842,8 @@ void handle_mqtt_req(MqttHelper *hlp, const void * const data, int len, string t ...@@ -818,8 +842,8 @@ void handle_mqtt_req(MqttHelper *hlp, const void * const data, int len, string t
} }
else { else {
auto str = fmt::format("unsupported cmd {}: {}", cmd, js.to_string()); auto str = fmt::format("unsupported cmd {}: {}", cmd, js.to_string());
spdlog::warn(str); spdlog::error(str);
MqttMgr::report_response_args(gMqttClient, consts::pub_topic_report, EV_MSG_ERROR_UNSUPPORTED_CMD, str, cmd, msg_field(js, consts::kMsgRid), json()); MqttMgr::report_response_args(gMqttClient, consts::pub_topic_report, EV_MSG_ERROR_UNSUPPORTED_CMD, str, cmd, rid, json());
} }
} }
......
...@@ -19,25 +19,34 @@ map<string, int> mapDirection = { ...@@ -19,25 +19,34 @@ map<string, int> mapDirection = {
{"upright", MOTOR_MOVE_RIGHT|MOTOR_MOVE_UP}, {"upright", MOTOR_MOVE_RIGHT|MOTOR_MOVE_UP},
{"upleft", MOTOR_MOVE_LEFT|MOTOR_MOVE_UP}, {"upleft", MOTOR_MOVE_LEFT|MOTOR_MOVE_UP},
{"downleft", MOTOR_MOVE_LEFT|MOTOR_MOVE_DOWN}, {"downleft", MOTOR_MOVE_LEFT|MOTOR_MOVE_DOWN},
{"downright", MOTOR_MOVE_RIGHT|MOTOR_MOVE_DOWN} {"downright", MOTOR_MOVE_RIGHT|MOTOR_MOVE_DOWN},
{"rightup", MOTOR_MOVE_RIGHT|MOTOR_MOVE_UP},
{"leftup", MOTOR_MOVE_LEFT|MOTOR_MOVE_UP},
{"leftdown", MOTOR_MOVE_LEFT|MOTOR_MOVE_DOWN},
{"rightdown", MOTOR_MOVE_RIGHT|MOTOR_MOVE_DOWN}
}; };
void ptz_waitfor_idle() void ptz_waitfor_idle()
{ {
XM_U32 action,x,y; XM_U32 action,x,y;
usleep(100*1000); usleep(100*1000);
int cnt = 5 * 10;
while (1) { while (cnt-- > 0) {
spdlog::info("ptz waiting");
if (0 == LibXmMaQue_Motor_getPostion(&action,&x,&y)) { if (0 == LibXmMaQue_Motor_getPostion(&action,&x,&y)) {
if (MOTOR_IDLE == action) { if (MOTOR_IDLE == action) {
break; break;
} }
else { else {
usleep(300*1000); usleep(200*1000);
} }
}else{
spdlog::error("ptz failed get position when waiting for idle");
break;
} }
} }
spdlog::info("ptz end wait");
} }
string ptz_service_start() string ptz_service_start()
...@@ -49,8 +58,12 @@ string ptz_service_start() ...@@ -49,8 +58,12 @@ string ptz_service_start()
rc = "ptz failed start service"; rc = "ptz failed start service";
return rc; return rc;
} }
if(first_startup) {
rc = ptz_reset();
first_startup = 0;
}else{
rc = ptz_load(); rc = ptz_load();
}
if(!rc.empty()) { if(!rc.empty()) {
return rc; return rc;
} }
...@@ -81,14 +94,15 @@ string ptz_get_params(ptz_param_position & param) ...@@ -81,14 +94,15 @@ string ptz_get_params(ptz_param_position & param)
} }
param.min_x = 0; param.min_x = 0;
param.max_x = x; param.max_x = x;
param.step_x = EV_PTZ_X_DEGREE/x; param.step_x = x/EV_PTZ_X_DEGREE;
param.current_x_deg = cx * param.step_x; param.current_x_deg = cx / param.step_x;
param.current_x_steps = cx; param.current_x_steps = cx;
param.min_y = 0; param.min_y = 0;
param.max_y = y; param.max_y = y;
param.step_y = EV_PTZ_Y_DEGREE/x; param.step_y = y/EV_PTZ_Y_DEGREE;
param.current_y_deg = cy * param.step_y; param.current_y_deg = cy / param.step_y;
param.current_y_steps = cy; param.current_y_steps = cy;
spdlog::info("ptz_get_params: max_x: {}, max_y: {}, current_x: {}, current_y: {}, step_x: {}, step_y: {}", param.max_x, param.max_y, param.current_x_steps, param.current_y_steps, param.step_x, param.step_y);
return rc; return rc;
} }
...@@ -98,7 +112,8 @@ static const string extraSysConfigFile = "/etc/evsys.json"; ...@@ -98,7 +112,8 @@ static const string extraSysConfigFile = "/etc/evsys.json";
string ptz_save() string ptz_save()
{ {
ptz_param_position pos; ptz_param_position pos;
auto rc = ptz_get_params(pos); string rc;
rc = ptz_get_params(pos);
if(!rc.empty()) { if(!rc.empty()) {
return rc; return rc;
} }
...@@ -107,7 +122,12 @@ string ptz_save() ...@@ -107,7 +122,12 @@ string ptz_save()
js["ptz"] = json(); js["ptz"] = json();
js["ptz"]["x"] = pos.current_x_steps; js["ptz"]["x"] = pos.current_x_steps;
js["ptz"]["y"] = pos.current_y_steps; js["ptz"]["y"] = pos.current_y_steps;
spdlog::info("ptz_save current: {}", js.to_string());
rc = save_json(js, extraSysConfigFile, true, evutils::make_default_sys_extra_config); rc = save_json(js, extraSysConfigFile, true, evutils::make_default_sys_extra_config);
if(!rc.empty()){
spdlog::error(rc);
}
spdlog::info("ptz_save current end: {}", js.to_string());
return rc; return rc;
} }
...@@ -119,20 +139,28 @@ string ptz_load() ...@@ -119,20 +139,28 @@ string ptz_load()
if(!rc.empty()) { if(!rc.empty()) {
return rc; return rc;
} }
rc = save_json(js, extraSysConfigFile, false, evutils::make_default_sys_extra_config);
if(!rc.empty()){
spdlog::error(rc);
return rc;
}
auto x = js["ptz"]["x"].as<uint32_t>(); auto x = js["ptz"]["x"].as<uint32_t>();
auto y = js["ptz"]["y"].as<uint32_t>(); auto y = js["ptz"]["y"].as<uint32_t>();
if(LibXmMaQue_Motor_setPostion(x,y)) { if(LibXmMaQue_Motor_setPostion(x,y)) {
rc = fmt::format("failed to set position to {}, {}", x, y); rc = fmt::format("failed to set position to {}, {}", x, y);
} }
spdlog::info("ptz load");
ptz_waitfor_idle(); ptz_waitfor_idle();
return rc; return rc;
} }
string ptz_move(string dire, float degree) string ptz_move(string dire, float degree)
{ {
lock_guard<mutex> lk(gMut);
string rc; string rc;
{
lock_guard<mutex> lk(gMut);
if(mapDirection.count(dire) == 0) { if(mapDirection.count(dire) == 0) {
rc = fmt::format("ptz move invalid direction: {}", dire); rc = fmt::format("ptz move invalid direction: {}", dire);
return rc; return rc;
...@@ -144,19 +172,27 @@ string ptz_move(string dire, float degree) ...@@ -144,19 +172,27 @@ string ptz_move(string dire, float degree)
return rc; return rc;
} }
if(dire == "left" || dire == "rignt") { if(dire.find("left") != string::npos || dire.find("right") != string::npos) {
curr_pos.current_x_steps = (degree *1.0 / curr_pos.step_x); curr_pos.current_x_steps = (degree * curr_pos.step_x);
}else{
curr_pos.current_x_steps = 0;
} }
if(dire == "up" || dire == "down") { if(dire.find("up")!= string::npos || dire.find("down") != string::npos ) {
curr_pos.current_y_steps = (degree *1.0 / curr_pos.step_y); curr_pos.current_y_steps = (degree * curr_pos.step_y);
}else{
curr_pos.current_y_steps = 0;
} }
spdlog::info("ptz executing: {}, {}", dire, degree);
spdlog::info("motor moving steps: {}, {}", curr_pos.current_x_steps, curr_pos.current_y_steps );
if(LibXmMaQue_Motor_move(mapDirection["dire"], 52, 52, curr_pos.current_x_steps, curr_pos.current_y_steps)< 0) { if(LibXmMaQue_Motor_move(mapDirection[dire], 6, 6, curr_pos.current_x_steps, curr_pos.current_y_steps) < 0) {
rc = fmt::format("ptz failed to move {} {}: current({},{}), max({},{})", dire, degree, curr_pos.current_x_deg, curr_pos.current_y_deg, 355, 0); rc = fmt::format("ptz failed to move {} {}: current({},{}), max({},{})", dire, degree, curr_pos.current_x_deg, curr_pos.current_y_deg, 355, 0);
if(!rc.empty()) { if(!rc.empty()) {
return rc; return rc;
} }
} }
}
ptz_waitfor_idle(); ptz_waitfor_idle();
rc = ptz_save(); rc = ptz_save();
...@@ -175,15 +211,19 @@ string ptz_reset() ...@@ -175,15 +211,19 @@ string ptz_reset()
auto targetx = param.max_x/2; auto targetx = param.max_x/2;
auto targety = param.max_y/2; auto targety = param.max_y/2;
if (LibXmMaQue_Motor_setZero()) { LibXmMaQue_Motor_setZero();
rc = "ptz failed to relocate to (0,0)"; spdlog::info("ptz set zero");
return rc; ptz_waitfor_idle();
} spdlog::info("ptz set to zero");
auto i = LibXmMaQue_Motor_move(mapDirection["upright"], 6, 6, targetx, targety);
if(LibXmMaQue_Motor_move(mapDirection["upright"], 52, 52, targetx, targety)< 0) { if(i< 0) {
rc = fmt::format("ptz failed move to center: {} {}", targetx, targety); rc = fmt::format("ptz failed move to center: {} {}", targetx, targety);
return rc;
} }
spdlog::info("ptz move to center");
ptz_waitfor_idle(); ptz_waitfor_idle();
spdlog::info("ptz end center");
return rc; return rc;
} }
\ No newline at end of file
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
/// PTZ /// PTZ
#define EV_PTZ_X_DEGREE 355 #define EV_PTZ_X_DEGREE 355
// N/A for xiongmai camera // N/A for xiongmai camera
#define EV_PTZ_Y_DEGREE -1 #define EV_PTZ_Y_DEGREE 355
// N/A for xiongmai camera // N/A for xiongmai camera
#define EV_PTZ_Z_DEGREE -1 #define EV_PTZ_Z_DEGREE -1
...@@ -19,17 +19,17 @@ typedef struct ptz_param_position { ...@@ -19,17 +19,17 @@ typedef struct ptz_param_position {
int max_x; int max_x;
int min_y; int min_y;
int max_y; // steps int max_y; // steps
float step_x; // degree per step float step_x; // steps per degree
float step_y; float step_y; // steps per degree
int current_x_deg; // in number of steps, not degree float current_x_deg; // in number of steps, not degree
int current_x_steps; int current_x_steps;
int current_y_deg; float current_y_deg;
int current_y_steps; // int current_y_steps; //
}ptz_param_position; }ptz_param_position;
std::string ptz_service_start(); std::string ptz_service_start();
std::string ptz_service_stop(); std::string ptz_service_stop();
std::string ptz_reset(ptz_param_position); std::string ptz_reset();
std::string ptz_move(std::string dire, float degree); std::string ptz_move(std::string dire, float degree);
std::string ptz_get_params(ptz_param_position & param); std::string ptz_get_params(ptz_param_position & param);
std::string ptz_load(); std::string ptz_load();
......
...@@ -65,7 +65,7 @@ XM_S32 MaQue_JpegEnc_getFrame_callback (XM_VOID *pUserArg, MaQueSmartJpegFrame_s ...@@ -65,7 +65,7 @@ XM_S32 MaQue_JpegEnc_getFrame_callback (XM_VOID *pUserArg, MaQueSmartJpegFrame_s
js[consts::kMsgType] = consts::kMsgTypeImage; js[consts::kMsgType] = consts::kMsgTypeImage;
js[consts::kMsgEncode] = consts::kMsgEncodeBase64; js[consts::kMsgEncode] = consts::kMsgEncodeBase64;
js[consts::kMsgFormat] = consts::kMsgFormatJpeg; js[consts::kMsgFormat] = consts::kMsgFormatJpeg;
MqttMgr::report_response_args(client, consts::pub_topic_response + client->id, 0, str, "ai_image", "", js); MqttMgr::report_response_args(mod->pClient, consts::pub_topic_response + mod->pClient->id, 0, str, "ai_image", "", js);
} }
return XM_SUCCESS; return XM_SUCCESS;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论