Projektarbeit Line Following Robot bei Prof. Chowanetz im WS22/23
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lfr_state_machine.cpp 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include "lfr_state_machine.h"
  2. // for string delimiter
  3. vector<string> LFR_StateMachine::split (string s, string delimiter) const {
  4. size_t pos_start = 0, pos_end, delim_len = delimiter.length();
  5. string token;
  6. vector<string> res;
  7. while ((pos_end = s.find (delimiter, pos_start)) != string::npos) {
  8. token = s.substr (pos_start, pos_end - pos_start);
  9. pos_start = pos_end + delim_len;
  10. res.push_back (token);
  11. }
  12. res.push_back (s.substr (pos_start));
  13. return res;
  14. }
  15. void LFR_StateMachine::sanitize (string& s) const
  16. {
  17. char r = '\r', n = '\n';
  18. s.erase(std::remove(s.begin(), s.end(), n), s.end());
  19. s.erase(std::remove(s.begin(), s.end(), r), s.end());
  20. }
  21. bool LFR_StateMachine::checkStringValidity (const std::vector<std::string>& s) const
  22. {
  23. try
  24. {
  25. int i = stoi(s[0]);
  26. if(i == 0 && s.size() == 5)
  27. {
  28. for(int i = 0; i < 4; i ++)
  29. {
  30. if(stod(s[i]) > 1.0 || stod(s[i]) < -1.0)
  31. {
  32. return false;
  33. }
  34. }
  35. }
  36. else if(i == 1)
  37. {
  38. return true;
  39. }
  40. else
  41. {
  42. return false;
  43. }
  44. }
  45. catch(const std::exception& e) {return false;}
  46. return true;
  47. }
  48. void LFR_StateMachine::parseString(string s)
  49. {
  50. sanitize(s);
  51. std::vector<std::string> splitStr = split(s, ";");
  52. if(!checkStringValidity(splitStr))
  53. {
  54. std::cout<<"Error: Invalid String: " << s << std::endl;
  55. return;
  56. }
  57. else
  58. {
  59. std::cout<< s << std::endl;
  60. }
  61. double wheels[4] = {0.0, 0.0, 0.0, 0.0};
  62. int mode = std::stoi(splitStr[0]);
  63. if(mode == 0) {
  64. for(int i = 1; i <= 4; i++)
  65. {
  66. wheels[i-1] = std::stod(splitStr[i]);
  67. }
  68. setState(State::Manual::getInstance());
  69. uartCommunicator.sendTelegram(wheels[0], wheels[1], wheels[2], wheels[3]);
  70. }
  71. else if (mode == 1) {setState(State::Autonomous::getInstance());}
  72. return;
  73. }
  74. LFR_StateMachine::LFR_StateMachine():
  75. autonomousMode(videoHeight, videoWidth, thresholdBinary, gaussKernelSize, maxSpeed, [&](std::exception const &ex)
  76. {
  77. std::unique_lock<std::mutex> lock(mutex);
  78. std::cerr<<"camera exception:"<<ex.what()<<std::endl;
  79. return false;
  80. }),
  81. uartCommunicator(),
  82. socket([&](std::exception const &ex)
  83. {
  84. std::unique_lock<std::mutex> lock(mutex);
  85. std::cerr<<"socket exception:"<<ex.what()<<std::endl;
  86. return false;
  87. })
  88. {
  89. // Connect String parser to socket
  90. socket.addListener([&](LFR_Socket::LFR_Telegram telegram)
  91. {
  92. std::unique_lock<std::mutex> lock(mutex);
  93. parseString(std::string(telegram));
  94. }, &mutex);
  95. socket.startLoop();
  96. currentState = &State::Idle::getInstance();
  97. currentState->enter(this);
  98. cv::VideoWriter writer = cv::VideoWriter("video_200.avi", cv::VideoWriter::fourcc('M','J','P','G'), 4.0, cv::Size(videoWidth, videoHeight), true);
  99. auto t_start = std::chrono::high_resolution_clock::now();
  100. auto t_end = std::chrono::high_resolution_clock::now();
  101. double dur = std::chrono::duration<double, std::milli>(t_end-t_start).count();
  102. while(dur < 60000)
  103. {
  104. t_end = std::chrono::high_resolution_clock::now();
  105. dur = std::chrono::duration<double, std::milli>(t_end-t_start).count();
  106. {
  107. this_thread::sleep_for(std::chrono::milliseconds(50));
  108. std::unique_lock<std::mutex> lock(imgMutex);
  109. if(!this->image.empty())
  110. {
  111. writer.write(this->image);
  112. }
  113. }
  114. }
  115. writer.release();
  116. std::cout << "Exiting central" << std::endl;
  117. }
  118. void LFR_StateMachine::setState(LFR_IState& newState)
  119. {
  120. if (&newState != currentState)
  121. {
  122. currentState->exit(this);
  123. currentState = &newState;
  124. currentState->enter(this);
  125. }
  126. }
  127. void LFR_StateMachine::enterAutonomous()
  128. {
  129. //cv::Mat img;
  130. autonomousMode.addListener([&](LFR_Result result)
  131. {
  132. std::unique_lock<std::mutex> lock(mutex);
  133. if (!result.rawImage.empty())
  134. {
  135. /*
  136. img = result.rawImage;
  137. //Resize to minimize latency using raspi over ssh/adapt to 3.5in screen
  138. cv::resize(result.rawImage, img, cv::Size(480, 320));
  139. //Calculate frame rate
  140. now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
  141. unsigned int deltaMs = static_cast<unsigned int>((now-last).count());
  142. double delta = static_cast<double>(deltaMs) / 1000.0;
  143. double frameRate = 1.0 / static_cast<double>(delta);*/
  144. double frameRate = -1.0;
  145. {
  146. std::unique_lock<std::mutex> lock(imgMutex);
  147. image = result.rawImage;
  148. }
  149. if (result.validLane)
  150. {
  151. std::cout << "Frame rate: " << frameRate << " angle: " << result.data.angle
  152. << " motor 1: " << result.motorSignals[0] << " motor 2: " << result.motorSignals[1]
  153. << " motor 3: " << result.motorSignals[2] << " motor 4: " << result.motorSignals[3] <<std::endl;
  154. uartCommunicator.sendTelegram(result.motorSignals[0], result.motorSignals[1], result.motorSignals[2], result.motorSignals[3]);
  155. }
  156. else
  157. {
  158. std::cout << "No lane found." << std::endl;;
  159. }
  160. //last = now;
  161. }
  162. }, &mutex);
  163. autonomousMode.startLoop();
  164. }
  165. void LFR_StateMachine::exitAutonomous()
  166. {
  167. autonomousMode.removeListener(&mutex);
  168. autonomousMode.endLoop();
  169. }