diff --git a/code/c++/cxx-api/AutoConnector.cpp b/code/c++/cxx-api/AutoConnector.cpp new file mode 100644 index 0000000..17b8a0e --- /dev/null +++ b/code/c++/cxx-api/AutoConnector.cpp @@ -0,0 +1,41 @@ +#include "AutoConnector.h" + +AutoConnector::AutoConnector(std::function c, uint32_t f) : pConnectingThread(nullptr), callback(c), + frequency(f) +{ + isRepeat.store(false); +} + +AutoConnector::~AutoConnector() { + stop(); +} + +void AutoConnector::start() { + if (!isRepeat.load() && !pConnectingThread) + { + Data d; + d.callback = callback; + d.pIsRepeat = &isRepeat; + d.frequency = frequency; + isRepeat.store(true); + pConnectingThread = new std::thread([d]() { + while (d.pIsRepeat->load()) + { + d.callback(); + std::this_thread::sleep_for(std::chrono::milliseconds(d.frequency)); + } + }); + } +} + +void AutoConnector::stop() { + if (isRepeat.load() && pConnectingThread) { + isRepeat.store(false); + pConnectingThread->join(); + delete pConnectingThread; + } +} + +bool AutoConnector::isConnecting() { + return isRepeat.load(); +} \ No newline at end of file diff --git a/code/c++/cxx-api/AutoConnector.h b/code/c++/cxx-api/AutoConnector.h new file mode 100644 index 0000000..5c0be5e --- /dev/null +++ b/code/c++/cxx-api/AutoConnector.h @@ -0,0 +1,26 @@ +#pragma once +#include +#include +#include +#include + +struct Data { + std::function callback; + std::atomic_bool* pIsRepeat; + uint32_t frequency; +}; + +class AutoConnector { +private: + std::thread* pConnectingThread; + std::function callback; + std::atomic_bool isRepeat; + uint32_t frequency; + +public: + AutoConnector(std::function c, uint32_t f = 500); + ~AutoConnector(); + void start(); + void stop(); + bool isConnecting(); +}; \ No newline at end of file diff --git a/code/c++/cxx-api/CommandsEnum.h b/code/c++/cxx-api/CommandsEnum.h index 94578ea..4f9fbee 100644 --- a/code/c++/cxx-api/CommandsEnum.h +++ b/code/c++/cxx-api/CommandsEnum.h @@ -48,6 +48,7 @@ enum ServoCommands { enum CommunicationCommands { startCommunicationCommand = 1, //starting communication command stopCommunicationCommand = 2, //stopping communication command + refreshConnectionCommunicationCommand = 3, //refreshing connection timer communication command (since API v3) }; /** @@ -56,7 +57,8 @@ enum CommunicationCommands { */ enum StartCommands { startBasicAPI = 1, //default API v1 - APIWithAnswer = 2 //API v2 + APIWithAnswer = 2, //API v2 + APIWithAutoDiconnect = 3 //API v3 }; #endif /* _COMMANDS_ENUM_H_ */ diff --git a/code/c++/cxx-api/TrackPlatform_BasicConnector.cpp b/code/c++/cxx-api/TrackPlatform_BasicConnector.cpp index fe793a3..50668e6 100644 --- a/code/c++/cxx-api/TrackPlatform_BasicConnector.cpp +++ b/code/c++/cxx-api/TrackPlatform_BasicConnector.cpp @@ -14,7 +14,7 @@ const std::string TrackPlatform_BasicConnector::correctAnswer = "OK"; void TrackPlatform_BasicConnector::sendStartCommand() { - std::string command = std::string() + static_cast(communicationControllerID) + static_cast(startCommunicationCommand) + static_cast(APIWithAnswer); + std::string command = std::string() + static_cast(communicationControllerID) + static_cast(startCommunicationCommand) + static_cast(APIWithAutoDiconnect); isConnectedToArduino = true; sendOneCommand(command); } diff --git a/code/c++/cxx-api/TrackPlatform_BasicManagement.cpp b/code/c++/cxx-api/TrackPlatform_BasicManagement.cpp index bc0c54f..95ea3a9 100644 --- a/code/c++/cxx-api/TrackPlatform_BasicManagement.cpp +++ b/code/c++/cxx-api/TrackPlatform_BasicManagement.cpp @@ -21,6 +21,12 @@ void TrackPlatform_BasicManagement::sendServo(const std::string& additionalInfo) readWriteAtomicMutex.unlock(); } +void TrackPlatform_BasicManagement::sendCommunication(const std::string& additionalInfo) { + readWriteAtomicMutex.lock(); + connector->sendOneCommand(static_cast(communicationControllerID) + additionalInfo); + readWriteAtomicMutex.unlock(); +} + std::vector TrackPlatform_BasicManagement::parseStringToArray(std::string s) { std::vector distancies; @@ -218,3 +224,8 @@ std::vector TrackPlatform_BasicManagement::servoGetAngles() readWriteAtomicMutex.unlock(); return parseStringToArray(answer); } + +void TrackPlatform_BasicManagement::refreshConnection() { + std::string toSend(1, refreshConnectionCommunicationCommand); + sendCommunication(toSend); +} \ No newline at end of file diff --git a/code/c++/cxx-api/TrackPlatform_BasicManagement.h b/code/c++/cxx-api/TrackPlatform_BasicManagement.h index c4d0020..6e8d6a5 100644 --- a/code/c++/cxx-api/TrackPlatform_BasicManagement.h +++ b/code/c++/cxx-api/TrackPlatform_BasicManagement.h @@ -11,14 +11,16 @@ class TrackPlatform_BasicManagement { TrackPlatform_BasicConnector* connector; +protected: static const uint8_t minSpeed = 0; static const uint8_t maxSpeed = 255; + static const uint32_t reconnectTime = 500; static const char delimiter = ';'; -protected: void sendMove(const std::string& additionalInfo); void sendSensors(const std::string& additionalInfo); void sendServo(const std::string& additionalInfo); + void sendCommunication(const std::string& additionalInfo); static std::vector parseStringToArray(std::string s); @@ -59,6 +61,9 @@ class TrackPlatform_BasicManagement void servoSetVerticalAngle(uint16_t angle); void servoSetHorizontalVerticalAngle(uint16_t horizontalAngle, uint16_t verticalAngle); std::vector servoGetAngles(); + + /* connection */ + void refreshConnection(); }; #endif /* _TRACKPLATFORM_BASICMANAGEMENT_H_ */ diff --git a/code/c++/cxx-api/TrackPlatform_Manager.cpp b/code/c++/cxx-api/TrackPlatform_Manager.cpp index 2ad92f4..ec3b710 100644 --- a/code/c++/cxx-api/TrackPlatform_Manager.cpp +++ b/code/c++/cxx-api/TrackPlatform_Manager.cpp @@ -24,16 +24,27 @@ TrackPlatform_BasicConnector* TrackPlatform_Manager::createConnectorByMode(Conne return res; } -TrackPlatform_Manager::TrackPlatform_Manager(ConnectionModes mode, const CommunicationInfoStruct& info) : +TrackPlatform_Manager::TrackPlatform_Manager(ConnectionModes mode, const CommunicationInfoStruct& info) : TrackPlatform_BasicManagement(createConnectorByMode(mode, info)) { + std::function callback = [this]() { this->refreshConnection(); }; + pAutoConnector = new AutoConnector(callback, reconnectTime); + pAutoConnector->start(); } TrackPlatform_Manager::~TrackPlatform_Manager() { + if (pAutoConnector) delete pAutoConnector; TrackPlatform_BasicConnector* connector = getConnector(); if (connector) { delete connector; } } + +void TrackPlatform_Manager::startAutoConnection() { + pAutoConnector->start(); +} +void TrackPlatform_Manager::stopAutoConnection() { + pAutoConnector->stop(); +} \ No newline at end of file diff --git a/code/c++/cxx-api/TrackPlatform_Manager.h b/code/c++/cxx-api/TrackPlatform_Manager.h index cd478e4..8cfae12 100644 --- a/code/c++/cxx-api/TrackPlatform_Manager.h +++ b/code/c++/cxx-api/TrackPlatform_Manager.h @@ -4,14 +4,19 @@ #include "TrackPlatform_BasicManagement.h" #include "ConnectionModes.h" #include "CommunicationInfoStruct.h" +#include "AutoConnector.h" class TrackPlatform_Manager : public TrackPlatform_BasicManagement { static TrackPlatform_BasicConnector* createConnectorByMode(ConnectionModes mode, const CommunicationInfoStruct& info); + AutoConnector* pAutoConnector = nullptr; public: TrackPlatform_Manager(ConnectionModes mode, const CommunicationInfoStruct& info); ~TrackPlatform_Manager(); + + void startAutoConnection(); + void stopAutoConnection(); }; #endif /* _TRACKPLATFORM_MANAGER_H_ */ diff --git a/code/c++/cxx-api/cxx-api.vcxproj b/code/c++/cxx-api/cxx-api.vcxproj index 8c75329..76781da 100644 --- a/code/c++/cxx-api/cxx-api.vcxproj +++ b/code/c++/cxx-api/cxx-api.vcxproj @@ -146,6 +146,7 @@ + @@ -171,6 +172,7 @@ + diff --git a/code/c++/cxx-api/cxx-api.vcxproj.filters b/code/c++/cxx-api/cxx-api.vcxproj.filters index 8ee1d7e..3fe8847 100644 --- a/code/c++/cxx-api/cxx-api.vcxproj.filters +++ b/code/c++/cxx-api/cxx-api.vcxproj.filters @@ -111,6 +111,9 @@ exceptions\header + + Communication\header + @@ -143,5 +146,8 @@ Source Files + + Communication\source + \ No newline at end of file diff --git a/code/c++/cxx-app/SensorsViewer.cpp b/code/c++/cxx-app/SensorsViewer.cpp new file mode 100644 index 0000000..202a9ad --- /dev/null +++ b/code/c++/cxx-app/SensorsViewer.cpp @@ -0,0 +1,53 @@ +#include "SensorsViewer.h" + + void SensorsViewer::setData(const std::vector& d, SensorType t) { + if (t == LINE_SENSORS) { + lineSensors = d; + } + else { + distanceSensors = d; + } + } + + void SensorsViewer::show() { + if (system("clear")) system("cls"); + if (!distanceSensors.empty()) { + if (system("clear")) system("cls"); + std::cout << "Distance sensors:" << std::endl; + if (distanceSensors.size() >= 1) std::cout << " " << std::setw(4) << distanceSensors[0] << std::endl; + if (distanceSensors.size() >= 2) std::cout << " " << std::setw(4) << distanceSensors[1] << (distanceSensors.size() == 2 ? "\n" : ""); + if (distanceSensors.size() >= 3) std::cout << " " << std::setw(4) << distanceSensors[2] << std::endl; + if (distanceSensors.size() >= 4) std::cout << " " << std::setw(4) << distanceSensors[3] << (distanceSensors.size() == 4 ? "\n" : ""); + if (distanceSensors.size() >= 5) std::cout << " " << std::setw(4) << distanceSensors[4] << std::endl; + } + if (!lineSensors.empty()) { + std::cout << "Line sensors:" << std::endl; + std::cout << "|"; + for (int i = 0; i < lineSensors.size(); i++) { + std::cout << (lineSensors[i] ? "@@@" : " "); + } + std::cout << "|"; + } + } + void SensorsViewer::show(SensorType type) { + if (type == LINE_SENSORS) { + if (!lineSensors.empty()) { + std::cout << "\r" << "|"; + for (int i = 0; i < lineSensors.size(); i++) { + std::cout << (lineSensors[i] ? "@@@" : " "); + } + std::cout << "|"; + } + } + else { + if (!distanceSensors.empty()) { + if (system("clear")) system("cls"); + std::cout << "Distance sensors:" << std::endl; + if (distanceSensors.size() >= 1) std::cout << " " << std::setw(4) << distanceSensors[0] << std::endl; + if (distanceSensors.size() >= 2) std::cout << " " << std::setw(4) << distanceSensors[1] << (distanceSensors.size() == 2 ? "\n" : ""); + if (distanceSensors.size() >= 3) std::cout << " " << std::setw(4) << distanceSensors[2] << std::endl; + if (distanceSensors.size() >= 4) std::cout << " " << std::setw(4) << distanceSensors[3] << (distanceSensors.size() == 4 ? "\n" : ""); + if (distanceSensors.size() >= 5) std::cout << " " << std::setw(4) << distanceSensors[4] << std::endl; + } + } +} \ No newline at end of file diff --git a/code/c++/cxx-app/SensorsViewer.h b/code/c++/cxx-app/SensorsViewer.h new file mode 100644 index 0000000..365b345 --- /dev/null +++ b/code/c++/cxx-app/SensorsViewer.h @@ -0,0 +1,19 @@ +#pragma once +#include +#include +#include +#include + +enum SensorType { + LINE_SENSORS, DISTANCE_SENSORS +}; + +class SensorsViewer { + std::vector lineSensors; + std::vector distanceSensors; + +public: + void setData(const std::vector& d, SensorType t); + void show(); + void show(SensorType type); +}; \ No newline at end of file diff --git a/code/c++/cxx-app/cxx-app.vcxproj b/code/c++/cxx-app/cxx-app.vcxproj index 6c8eb23..32a43a6 100644 --- a/code/c++/cxx-app/cxx-app.vcxproj +++ b/code/c++/cxx-app/cxx-app.vcxproj @@ -167,6 +167,10 @@ + + + + diff --git a/code/c++/cxx-app/cxx-app.vcxproj.filters b/code/c++/cxx-app/cxx-app.vcxproj.filters index 0d8d9e4..823c170 100644 --- a/code/c++/cxx-app/cxx-app.vcxproj.filters +++ b/code/c++/cxx-app/cxx-app.vcxproj.filters @@ -18,5 +18,13 @@ Source Files + + Source Files + + + + + Header Files + \ No newline at end of file diff --git a/code/c++/cxx-app/main.cpp b/code/c++/cxx-app/main.cpp index c2ec410..90f81bb 100644 --- a/code/c++/cxx-app/main.cpp +++ b/code/c++/cxx-app/main.cpp @@ -9,9 +9,11 @@ #endif #include "TrackPlatform_Manager.h" +#include "SensorsViewer.h" int main(int argc, char* argv[]) { + std::string rx = "COM13", tx = "COM13"; uint32_t baudrate = 9600U; @@ -26,7 +28,7 @@ int main(int argc, char* argv[]) std::cin >> baudrate; */ std::cout << "rx = " << rx << " tx = " << tx << " baudrate = " << baudrate << " ip = " << ip << " port = " << port << std::endl; - + try { CommunicationInfoStruct info; @@ -37,11 +39,12 @@ int main(int argc, char* argv[]) TrackPlatform_Manager trackPlatform(bluetooth, info); #else + info.TCPIPInfo.ip = ip; info.TCPIPInfo.port = port; TrackPlatform_Manager trackPlatform(WiFi, info); + #endif - bool isExit = false; while (!isExit) { @@ -61,8 +64,10 @@ int main(int argc, char* argv[]) std::cout << " : stop" << std::endl; std::cout << "r: get all line values" << std::endl; std::cout << "e: get fixed line value" << std::endl; + std::cout << "u: show line sensors" << std::endl; std::cout << "t: get all distance values" << std::endl; std::cout << "y: get fixed distance value" << std::endl; + std::cout << "i: show distance sensors" << std::endl; std::cout << "g: set horisontal servo angle in degree" << std::endl; std::cout << "h: set vertical servo angle in degree" << std::endl; break; @@ -101,6 +106,14 @@ int main(int argc, char* argv[]) std::cout << "Value: " << trackPlatform.sensorLineGetValue(a) << std::endl; break; } + case 'u': + { + SensorsViewer sv; + auto arr = trackPlatform.sensorLineGetAllValues(); + sv.setData(arr, LINE_SENSORS); + std::cout << std::endl; + sv.show(); + } case 't': { auto arr = trackPlatform.sensorDistanceGetAllValues(); @@ -118,6 +131,14 @@ int main(int argc, char* argv[]) std::cout << "Value: " << trackPlatform.sensorDistanceGetValue(a) << std::endl; break; } + case 'i': + { + SensorsViewer sv; + auto arr = trackPlatform.sensorDistanceGetAllValues(); + sv.setData(arr, DISTANCE_SENSORS); + std::cout << std::endl; + sv.show(); + } case 'g': { std::cout << "Input num: ";