diff --git a/.gitignore b/.gitignore index 4921ec138..28b60002f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Microsoft Visual Studio Code .project .vscode/ - +build/* # Auto-generated shared/version.hpp diff --git a/host/py_module/py_bindings.cpp b/host/py_module/py_bindings.cpp index 273d00a49..7c6b28da5 100644 --- a/host/py_module/py_bindings.cpp +++ b/host/py_module/py_bindings.cpp @@ -29,12 +29,87 @@ #include "../../shared/json_helper.hpp" #include "../../shared/version.hpp" #include "../../shared/xlink/xlink_wrapper.hpp" -#include "test_data_subject.hpp" #include "../core/host_json_helper.hpp" namespace py = pybind11; +std::string config_backup; +std::string cmd_backup; +std::string usb_device_backup; +std::shared_ptr gl_result = nullptr; + +static volatile std::atomic wdog_keep; + +bool deinit_device(); +bool init_device( + const std::string &device_cmd_file, + const std::string &usb_device +); +std::shared_ptr create_pipeline( + const std::string &config_json_str +); + +static int wdog_thread_alive = 1; +void wdog_thread(int& wd_timeout_ms) +{ + std::cout << "watchdog started " << wd_timeout_ms << std::endl; + while(wdog_thread_alive) + { + wdog_keep = 0; + std::this_thread::sleep_for(std::chrono::milliseconds(wd_timeout_ms)); + if(wdog_keep == 0 && wdog_thread_alive == 1) + { + std::cout << "watchdog triggered " << std::endl; + deinit_device(); + bool init; + for(int retry = 0; retry < 1; retry++) + { + init = init_device(cmd_backup, usb_device_backup); + if(init) + { + break; + } + } + if(!init) + { + exit(9); + } + create_pipeline(config_backup); + } + } + +} + +static std::thread wd_thread; +static int wd_timeout_ms = 1000; +int wdog_start(void) +{ + static int once = 1; + if(once) + { + wdog_thread_alive = 1; + wd_thread = std::thread(wdog_thread, std::ref(wd_timeout_ms)); + once = 0; + } + return 0; +} +int wdog_stop(void) +{ + wdog_thread_alive = 0; + wd_thread.join(); + + return 0; +} + +//todo +extern "C" { +void wdog_keepalive(void) +{ + wdog_keep = 1; +} + +}; // TODO: REMOVE, IT'S TEMPORARY (for test only) static XLinkGlobalHandler_t g_xlink_global_handler = @@ -67,7 +142,6 @@ json g_config_d2h; std::unique_ptr g_disparity_post_proc; std::unique_ptr g_device_support_listener; -std::vector> g_test_data_subjects; @@ -76,6 +150,8 @@ bool init_device( const std::string &usb_device ) { + cmd_backup = device_cmd_file; + usb_device_backup = usb_device; bool result = false; std::string error_msg; @@ -96,13 +172,14 @@ bool init_device( &g_xlink_device_handler, device_cmd_file, usb_device, - true) + false) ) { std::cout << "depthai: Error initializing xlink\n"; break; } + wdog_start(); // config_d2h { @@ -115,7 +192,10 @@ bool init_device( si, config_d2h_str ); - + if(config_file_length == -1) + { + break; + } if (!getJSONFromString(config_d2h_str, g_config_d2h)) { std::cout << "depthai: error parsing config_d2h\n"; @@ -163,6 +243,13 @@ bool init_device( return result; } +bool deinit_device() +{ + g_xlink = nullptr; + g_disparity_post_proc = nullptr; + g_device_support_listener = nullptr; + return true; +} std::vector get_available_steams() { @@ -183,58 +270,11 @@ std::vector get_available_steams() } -std::unique_ptr create_pipeline_TEST( - const std::vector &streams, - const std::string &blob_file_config -) -{ - std::unique_ptr result; - - bool init_ok = false; - do - { - // read - std::vector tensors_info; - if (parseTensorInfosFromJsonFile(blob_file_config, tensors_info)) - { - printf("CNN configurations read: %s", blob_file_config.c_str()); - } - else - { - printf("There is no cnn configuration file or error in it\'s parsing: %s", blob_file_config.c_str()); - } - - // pipeline - result = std::unique_ptr(new CNNHostPipeline(tensors_info)); - - for (const std::string &stream_name : streams) - { - g_test_data_subjects.push_back(std::unique_ptr(new TestDataSubject)); - g_test_data_subjects.back()->runInThread(c_streams_myriad_to_pc.at(stream_name)); - - result->makeStreamPublic(stream_name); - result->observe(*g_test_data_subjects.back(), c_streams_myriad_to_pc.at(stream_name)); - } - - init_ok = true; - std::cout << "depthai: INIT OK!\n"; - } - while (false); - - if (!init_ok) - { - result = nullptr; - } - - return result; -} - - -std::unique_ptr create_pipeline( +std::shared_ptr create_pipeline( const std::string &config_json_str ) { - std::unique_ptr result; + config_backup = config_json_str; bool init_ok = false; do @@ -505,7 +545,8 @@ std::unique_ptr create_pipeline( // pipeline - result = std::unique_ptr(new CNNHostPipeline(tensors_info)); + if(gl_result == nullptr) + gl_result = std::shared_ptr(new CNNHostPipeline(tensors_info)); for (const std::string &stream_name : pipeline_device_streams) { @@ -513,8 +554,8 @@ std::unique_ptr create_pipeline( if (g_xlink->openStreamInThreadAndNotifyObservers(c_streams_myriad_to_pc.at(stream_name))) { - result->makeStreamPublic(stream_name); - result->observe(*g_xlink.get(), c_streams_myriad_to_pc.at(stream_name)); + gl_result->makeStreamPublic(stream_name); + gl_result->observe(*g_xlink.get(), c_streams_myriad_to_pc.at(stream_name)); } else { @@ -546,14 +587,14 @@ std::unique_ptr create_pipeline( if (add_disparity_post_processing_color) { - result->makeStreamPublic(stream_out_color_name); - result->observe(*g_disparity_post_proc.get(), c_streams_myriad_to_pc.at(stream_out_color_name)); + gl_result->makeStreamPublic(stream_out_color_name); + gl_result->observe(*g_disparity_post_proc.get(), c_streams_myriad_to_pc.at(stream_out_color_name)); } if (add_disparity_post_processing_mm) { - result->makeStreamPublic(stream_out_mm_name); - result->observe(*g_disparity_post_proc.get(), c_streams_myriad_to_pc.at(stream_out_mm_name)); + gl_result->makeStreamPublic(stream_out_mm_name); + gl_result->observe(*g_disparity_post_proc.get(), c_streams_myriad_to_pc.at(stream_out_mm_name)); } } else @@ -564,7 +605,7 @@ std::unique_ptr create_pipeline( } } - if (!result->setHostCalcDepthConfigs( + if (!gl_result->setHostCalcDepthConfigs( config.depth.type, config.depth.padding_factor, config.board_config.left_fov_deg, @@ -583,10 +624,10 @@ std::unique_ptr create_pipeline( if (!init_ok) { - result = nullptr; + gl_result = nullptr; } - return result; + return gl_result; } @@ -614,6 +655,12 @@ PYBIND11_MODULE(depthai, m) py::arg("cmd_file") = device_cmd_file, py::arg("usb_device") = usb_device ); + + m.def( + "deinit_device", + &deinit_device, + "Function that destroys the connection with device." + ); // reboot m.def( @@ -633,12 +680,6 @@ PYBIND11_MODULE(depthai, m) "Returns available streams, that possible to retreive from the device." ); - std::vector streams_default_cnn = {"metaout"}; - std::string device_calibration_file_cnn = "./depthai.calib"; - std::string blob_file_cnn = "./mobilenet-ssd-4b17b0a707.blob"; - std::string blob_file_config_cnn = "./mobilenet_ssd.json"; - std::string depth_type_cnn = ""; - // cnn pipeline m.def( "create_pipeline", @@ -660,15 +701,6 @@ PYBIND11_MODULE(depthai, m) ); - m.def( - "create_pipeline_TEST", - &create_pipeline_TEST, - "Function for development tests", - py::arg("streams") = streams_default_cnn, - py::arg("blob_file_config") = blob_file_config_cnn - ); - - // for PACKET in data_packets: py::class_>(m, "DataPacket") .def_readonly("stream_name", &HostDataPacket::stream_name) @@ -762,10 +794,9 @@ PYBIND11_MODULE(depthai, m) // module destructor auto cleanup_callback = []() { - g_xlink = nullptr; - g_disparity_post_proc = nullptr; - g_device_support_listener = nullptr; - g_test_data_subjects.clear(); + wdog_stop(); + deinit_device(); + gl_result = nullptr; }; m.add_object("_cleanup", py::capsule(cleanup_callback)); diff --git a/host/py_module/test_data_subject.hpp b/host/py_module/test_data_subject.hpp deleted file mode 100644 index d4255b330..000000000 --- a/host/py_module/test_data_subject.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "stream/stream_data.hpp" -#include "stream/stream_info.hpp" -#include "general/data_subject.hpp" - - -class TestDataSubject - : public DataSubject -{ -public: - TestDataSubject() {} - - virtual ~TestDataSubject() - { - _thr_exit_flag = true; - if (nullptr != _thr) - { - _thr->join(); - } - } - - - void runInThread(const StreamInfo &stream_info) - { - unsigned sz = (stream_info.size == 0) ? 1400 : stream_info.size; - _data = std::vector(sz, 0); - - _thr = std::unique_ptr( - new std::thread( - &TestDataSubject::threadFunc, this, stream_info) - ); - } - -private: - void threadFunc(const StreamInfo &stream_info) - { - int counter = 0; - - while (!_thr_exit_flag) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - - StreamData data; - data.data = _data.data(); - data.size = _data.size(); - data.packet_number = counter; - - this->notifyObservers(stream_info, data); - - counter += 1; - - std::cout << "TestDataSubject: tick\n"; - } - } - - std::vector _data; - std::unique_ptr _thr; - bool _thr_exit_flag = false; -}; diff --git a/shared/version.hpp b/shared/version.hpp new file mode 100644 index 000000000..688831204 --- /dev/null +++ b/shared/version.hpp @@ -0,0 +1,4 @@ +#pragma once + +const char *c_depthai_dev_version = "unknown"; +const char *c_depthai_version = "0.0.10a"; diff --git a/shared/xlink/xlink_wrapper.cpp b/shared/xlink/xlink_wrapper.cpp index 1d53eae44..03b3820c3 100644 --- a/shared/xlink/xlink_wrapper.cpp +++ b/shared/xlink/xlink_wrapper.cpp @@ -11,9 +11,8 @@ #include "xlink_wrapper.hpp" // FIXME use some header -#if !defined(__PC__) extern "C" void wdog_keepalive(void); -#endif + XLinkWrapper::XLinkWrapper( bool be_verbose @@ -233,6 +232,7 @@ uint32_t XLinkWrapper::openReadAndCloseStream( if (stream_id == int(INVALID_STREAM_ID)) { printf("Stream not opened: %s\n", stream.name); + result = -1; break; } @@ -246,7 +246,7 @@ uint32_t XLinkWrapper::openReadAndCloseStream( memcpy(&stl_container[0], packet->data, packet->length); result = packet->length; - + wdog_keepalive(); // release data status = XLinkReleaseData(stream_id); if (status != X_LINK_SUCCESS) @@ -304,7 +304,7 @@ uint32_t XLinkWrapper::openReadAndCloseStream( uint32_t copy_sz = std::min(buffer_size, packet->length); memcpy(buffer, packet->data, copy_sz); result = copy_sz; - + wdog_keepalive(); // release data status = XLinkReleaseData(stream_id); if (status != X_LINK_SUCCESS) @@ -539,9 +539,8 @@ bool XLinkWrapper::writeToStream( printf("!!! XLink write successful: %s (%d)\n", stream.name, int(write_data_size)); #endif -#if !defined(__PC__) - wdog_keepalive(); -#endif + wdog_keepalive(); + } return status == X_LINK_SUCCESS; @@ -643,7 +642,7 @@ void XLinkWrapper::openAndReadDataThreadFunc( // printf ("Stream id #%d | Name %10s | Packet size: %8u | No.: %4u\n", // stream_id, stream_info.name, packet->length, packet_counter); // } - + wdog_keepalive(); notifyObservers(stream_info, data); packet_counter += 1; diff --git a/shared/xlink/xlink_wrapper.hpp b/shared/xlink/xlink_wrapper.hpp index 7eda74f42..32448106e 100644 --- a/shared/xlink/xlink_wrapper.hpp +++ b/shared/xlink/xlink_wrapper.hpp @@ -85,7 +85,7 @@ class XLinkWrapper void closeAllObserverStreams(); - const int c_stream_open_tries = -1; + const int c_stream_open_tries = 5; const unsigned c_stream_write_timeout_ms = 5000; const unsigned c_stream_write_wait_ms = 1; // const int c_stream_write_tries = 20; @@ -101,7 +101,7 @@ class XLinkWrapper int _device_link_id = -1; // -1 stands for undefined - bool _threads_exit = false; + volatile bool _threads_exit = false; std::mutex _threads_subject_list_lock; // used in: openStreamInThreadAndNotifyObservers, waitForThreads std::list _threads_subject;