#include "lfr_state_machine.h" // for string delimiter vector LFR_StateMachine::split (string s, string delimiter) const { size_t pos_start = 0, pos_end, delim_len = delimiter.length(); string token; vector res; while ((pos_end = s.find (delimiter, pos_start)) != string::npos) { token = s.substr (pos_start, pos_end - pos_start); pos_start = pos_end + delim_len; res.push_back (token); } res.push_back (s.substr (pos_start)); return res; } void LFR_StateMachine::sanitize (string& s) const { char r = '\r', n = '\n'; s.erase(std::remove(s.begin(), s.end(), n), s.end()); s.erase(std::remove(s.begin(), s.end(), r), s.end()); } bool LFR_StateMachine::checkStringValidity (const std::vector& s) const { try { int i = stoi(s[0]); if(i == 0 && s.size() == 5) { for(int i = 0; i < 4; i ++) { if(stod(s[i]) > 1.0 || stod(s[i]) < -1.0) { return false; } } } else if(i == 1) { return true; } else { return false; } } catch(const std::exception& e) {return false;} return true; } void LFR_StateMachine::parseString(string s) { sanitize(s); std::vector splitStr = split(s, ";"); if(!checkStringValidity(splitStr)) { std::cout<<"Error: Invalid String: " << s << std::endl; return; } else { std::cout<< s << std::endl; } double wheels[4] = {0.0, 0.0, 0.0, 0.0}; int mode = std::stoi(splitStr[0]); if(mode == 0) { for(int i = 1; i <= 4; i++) { wheels[i-1] = std::stod(splitStr[i]); } setState(State::Manual::getInstance()); uartCommunicator.sendTelegram(wheels[0], wheels[1], wheels[2], wheels[3]); } else if (mode == 1) {setState(State::Autonomous::getInstance());} return; } LFR_StateMachine::LFR_StateMachine(): autonomousMode(videoHeight, videoWidth, thresholdBinary, gaussKernelSize, maxSpeed, [&](std::exception const &ex) { std::unique_lock lock(mutex); std::cerr<<"camera exception:"< lock(mutex); std::cerr<<"socket exception:"< lock(mutex); parseString(std::string(telegram)); }, &mutex); socket.startLoop(); currentState = &State::Idle::getInstance(); currentState->enter(this); cv::VideoWriter writer = cv::VideoWriter("video_200.avi", cv::VideoWriter::fourcc('M','J','P','G'), 4.0, cv::Size(videoWidth, videoHeight), true); auto t_start = std::chrono::high_resolution_clock::now(); auto t_end = std::chrono::high_resolution_clock::now(); double dur = std::chrono::duration(t_end-t_start).count(); while(dur < 60000) { t_end = std::chrono::high_resolution_clock::now(); dur = std::chrono::duration(t_end-t_start).count(); { this_thread::sleep_for(std::chrono::milliseconds(50)); std::unique_lock lock(imgMutex); if(!this->image.empty()) { writer.write(this->image); } } } writer.release(); std::cout << "Exiting central" << std::endl; } void LFR_StateMachine::setState(LFR_IState& newState) { if (&newState != currentState) { currentState->exit(this); currentState = &newState; currentState->enter(this); } } void LFR_StateMachine::enterAutonomous() { //cv::Mat img; autonomousMode.addListener([&](LFR_Result result) { std::unique_lock lock(mutex); if (!result.rawImage.empty()) { /* img = result.rawImage; //Resize to minimize latency using raspi over ssh/adapt to 3.5in screen cv::resize(result.rawImage, img, cv::Size(480, 320)); //Calculate frame rate now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); unsigned int deltaMs = static_cast((now-last).count()); double delta = static_cast(deltaMs) / 1000.0; double frameRate = 1.0 / static_cast(delta);*/ double frameRate = -1.0; { std::unique_lock lock(imgMutex); image = result.rawImage; } if (result.validLane) { std::cout << "Frame rate: " << frameRate << " angle: " << result.data.angle << " motor 1: " << result.motorSignals[0] << " motor 2: " << result.motorSignals[1] << " motor 3: " << result.motorSignals[2] << " motor 4: " << result.motorSignals[3] <