main.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  1. #include <iostream>
  2. #include <fstream>
  3. #include <ctime>
  4. #include <vector>
  5. #include <malloc.h>
  6. #include <algorithm>
  7. #include <thread>
  8. #include <chrono>
  9. #include <cmath>
  10. #include <sstream>
  11. #include <string>
  12. #include <iomanip>
  13. #include <cstdint>
  14. #include <bitset>
  15. #include <windows.h>
  16. #include "src/PassiveSocket.h"
  17. #include <stdio.h>
  18. #include "simplelogger.hpp"
  19. using namespace std;
  20. void delay(int msec)
  21. {
  22. clock_t start_time = clock();
  23. while (clock() < start_time + msec)
  24. {
  25. }
  26. }
  27. // Decoding functions
  28. //////////////////////////////////////////////////////////////
  29. int decode_get_api_version(uint8_t *buf, size_t bytes_recieved) {
  30. /*
  31. Decoding response for get_api_revision
  32. One word is 2 bytes
  33. 1st word: 0xAAAA (always)
  34. 2nd word: 0X010C (always for get_api_revision)
  35. 3rd word: Major Version (uint16_t)
  36. 4th word: Minor Version (uint16_t)
  37. 5th word: Patch Version (uint16_t)
  38. */
  39. // Check if buffer has at least 4 bytes for magic number and command
  40. if(bytes_recieved < 4)
  41. {
  42. cout << "Invalid buffer size" << endl;
  43. return -1;
  44. }
  45. // Extract magic number from buffer
  46. uint16_t magic;
  47. memcpy(&magic, buf, sizeof(uint16_t));
  48. // Check if magic number is correct
  49. if (magic != 0xAAAA) {
  50. cout << "Invalid magic number: " << std::hex << magic << endl;
  51. return -1;
  52. }
  53. // Extract command from buffer
  54. uint16_t cmd;
  55. memcpy(&cmd, buf + 2, sizeof(uint16_t));
  56. // Check if command is correct
  57. if (cmd != 0x010C) {
  58. cout << "Invalid command: " << std::hex << cmd << endl;
  59. return -1;
  60. }
  61. // Check if buffer has enough data for version numbers
  62. if(bytes_recieved < 10)
  63. {
  64. cout << "Wrong data size: " << bytes_recieved << endl;
  65. for(int i = 0; i < bytes_recieved; i++)
  66. {
  67. printf("0x%02X\n", (unsigned int)(buf[i]));
  68. }
  69. cout << endl;
  70. return -1;
  71. }
  72. // Extract version numbers from buffer
  73. uint16_t major_version, minor_version, patch_version;
  74. memcpy(&major_version, buf + 4, sizeof(uint16_t));
  75. memcpy(&minor_version, buf + 6, sizeof(uint16_t));
  76. memcpy(&patch_version, buf + 8, sizeof(uint16_t));
  77. // Print version
  78. cout << "API Version: " << major_version << "." << minor_version << "." << patch_version << endl;
  79. return 0;
  80. }
  81. int decode_get_gru_state(uint8_t *buf, size_t bytes_recieved) {
  82. /*
  83. Decoding response for get_board_state
  84. One word is 2 bytes
  85. 1st word: 0xAAAA (always)
  86. 2nd word: 0x0105 (always for get_gru_state)
  87. 3rd word: State code (uint16_t)
  88. 4th word: not used
  89. 5th and 6th words: Error bits (uint32_t)
  90. 7th and 8th words: Error point number (uint32_t)
  91. 9th and 10th words: Current setting amp (int32_t)
  92. 11th and 12th words: Current amp (int32_t)
  93. 13th and 14th words: First sensor value (int32_t)
  94. 15th and 16th words: Second sensor value (int32_t)
  95. 17th word: Debug info (uint16_t)
  96. 5-17 words have sense only if state code is error
  97. State codes:
  98. 0 - GRU_STATE_INIT
  99. 1 - GRU_STATE_INIT_FAILED
  100. 2 - GRU_STATE_IDLE
  101. 3 - GRU_STATE_SELFTEST
  102. 4 - GRU_STATE_SELFTEST_FAILED
  103. 5 - GRU_STATE_WAIT_TRAJECT
  104. 6 - GRU_STATE_WAIT_SYNC
  105. 7 - GRU_STATE_WORKING
  106. 8 - GRU_STATE_WORK_FAILED
  107. Error bits:
  108. 0x00000001 - OVERCURRENT_1
  109. 0x00000002 - OVERCURRENT_2
  110. 0x00000004 - CURRENT_SENSORS_MISMATCH
  111. 0x00000008 - POWER_SWITCH_SW_FAILURE
  112. 0x00000010 - WRONG_SIMULINK_MAGIC_NUMBER
  113. 0x00000020 - DC_OK_1
  114. 0x00000040 - POWER_SWITCH_HW_FAILURE
  115. 0x00000080 - SENSOR1_TRIP_HI
  116. 0x00000100 - SENSOR1_TRIP_LO
  117. 0x00000200 - SENSOR2_TRIP_HI
  118. 0x00000400 - SENSOR2_TRIP_LO
  119. 0x00000800 - TEMPER_1
  120. 0x00002000 - DC_OK_2
  121. 0x00004000 - TEMPER_2
  122. */
  123. // Check if buffer is big enough
  124. if(bytes_recieved < 4) {
  125. cout << "Invalid buffer size (no magic)" << endl;
  126. return -1;
  127. }
  128. uint16_t magic;
  129. memcpy(&magic, buf, sizeof(uint16_t));
  130. // Check if magic correct
  131. if (magic != 0xAAAA) {
  132. cout << "Invalid magic number: " << std::hex << magic << endl;
  133. return -1;
  134. }
  135. uint16_t cmd;
  136. memcpy(&cmd, buf + 2, sizeof(uint16_t));
  137. // Check if command are correct
  138. if (cmd != 0x0105) {
  139. cout << "Invalid command: " << std::hex << cmd << endl;
  140. return -1;
  141. }
  142. // Check if buffer has enough data
  143. if(bytes_recieved < 6) {
  144. cout << "Wrong state data size: " << bytes_recieved << endl;
  145. return -1;
  146. }
  147. // Extract state code from buffer
  148. uint16_t state_code;
  149. memcpy(&state_code, buf + 4, sizeof(uint16_t));
  150. // Print state code
  151. cout << "State code " << state_code << ": ";
  152. // Decode and print state code description
  153. switch(state_code)
  154. {
  155. case 0:
  156. cout << "GRU_STATE_INIT" << endl;
  157. break;
  158. case 1:
  159. cout << "GRU_STATE_INIT_FAILED" << endl;
  160. break;
  161. case 2:
  162. cout << "GRU_STATE_IDLE" << endl;
  163. break;
  164. case 3:
  165. cout << "GRU_STATE_SELFTEST" << endl;
  166. break;
  167. case 4:
  168. cout << "GRU_STATE_SELFTEST_FAILED" << endl;
  169. break;
  170. case 5:
  171. cout << "GRU_STATE_WAIT_TRAJECT" << endl;
  172. break;
  173. case 6:
  174. cout << "GRU_STATE_WAIT_SYNC" << endl;
  175. break;
  176. case 7:
  177. cout << "GRU_STATE_WORKING" << endl;
  178. break;
  179. case 8:
  180. cout << "GRU_STATE_WORK_FAILED" << endl;
  181. break;
  182. default:
  183. cout << "Unknown state" << endl;
  184. break;
  185. }
  186. // If there are more than 6 bytes, extract error data
  187. uint32_t error_bits, error_point_number;
  188. int32_t current_setting_amp, current_amp, first_sensor_value, second_sensor_value;
  189. uint16_t debug_info;
  190. if(bytes_recieved > 6) {
  191. // Check if buffer has enough data for error information
  192. if(bytes_recieved < 34) {
  193. cout << "Wrong error data size: " << bytes_recieved << endl;
  194. return -1;
  195. }
  196. // Extract error data from buffer
  197. memcpy(&error_bits, buf + 8, sizeof(uint32_t));
  198. memcpy(&error_point_number, buf + 12, sizeof(uint32_t));
  199. memcpy(&current_setting_amp, buf + 16, sizeof(int32_t));
  200. memcpy(&current_amp, buf + 20, sizeof(int32_t));
  201. memcpy(&first_sensor_value, buf + 24, sizeof(int32_t));
  202. memcpy(&second_sensor_value, buf + 28, sizeof(int32_t));
  203. memcpy(&debug_info, buf + 32, sizeof(uint16_t));
  204. }
  205. else
  206. {
  207. // Initialize error data to zero if not enough bytes received
  208. error_bits = 0;
  209. error_point_number = 0;
  210. current_setting_amp = 0;
  211. current_amp = 0;
  212. first_sensor_value = 0;
  213. second_sensor_value = 0;
  214. debug_info = 0;
  215. }
  216. // If state code indicates an error, print error details
  217. if(state_code == 1 || state_code == 4 || state_code == 8)
  218. {
  219. cout << "Error bits: " << error_bits << endl;
  220. cout << "Error point number: " << error_point_number << endl;
  221. cout << "Current setting amp: " << current_setting_amp << endl;
  222. cout << "Current amp: " << current_amp << endl;
  223. cout << "First sensor value: " << first_sensor_value << endl;
  224. cout << "Second sensor value: " << second_sensor_value << endl;
  225. cout << "Debug info: " << debug_info << endl;
  226. return -1;
  227. }
  228. return 0;
  229. }
  230. int decode_get_sw_revision(uint8_t *buf, size_t bytes_recieved) {
  231. /*
  232. Decoding response for get_sw_revision
  233. One word is 2 bytes
  234. 1st word: 0xAAAA (always)
  235. 2nd word: 0x010D (always for get_sw_revision)
  236. Other words: Unicode string (wchar_t*)
  237. */
  238. // Check if buffer has at least 4 bytes for magic number and command
  239. if(bytes_recieved < 4) {
  240. cout << "Invalid buffer size" << endl;
  241. return -1;
  242. }
  243. // Extract magic number from buffer
  244. uint16_t magic;
  245. memcpy(&magic, buf, sizeof(uint16_t));
  246. // Check if magic number is correct
  247. if (magic != 0xAAAA) {
  248. cout << "Invalid magic number: " << std::hex << magic << endl;
  249. return -1;
  250. }
  251. // Extract command from buffer
  252. uint16_t cmd;
  253. memcpy(&cmd, buf + 2, sizeof(uint16_t));
  254. // Check if command is correct
  255. if (cmd != 0x010D) {
  256. cout << "Invalid command: " << std::hex << cmd << endl;
  257. return -1;
  258. }
  259. // Check if buffer has enough data and is even-sized
  260. if(bytes_recieved < 6 || bytes_recieved % 2 != 0) {
  261. cout << "Wrong data size: " << bytes_recieved << endl;
  262. return -1;
  263. }
  264. // Extract software revision string from buffer
  265. char16_t sw_revision[1024];
  266. memcpy(sw_revision, buf + 4, bytes_recieved - 4);
  267. sw_revision[(bytes_recieved - 4) / 2] = u'\0'; // Null-terminate the string
  268. // Print software revision string
  269. #ifdef _WIN32 // Convert to wide string on Windows
  270. wcout << L"Software revision: " << reinterpret_cast<wchar_t*>(sw_revision) << endl;
  271. #elif __linux__ // Using UTF-8 on Linux (converted by codecvt)
  272. std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
  273. std::string converted_str = converter.to_bytes(sw_revision);
  274. cout << "Software revision: " << converted_str << endl;
  275. #endif
  276. return 0;
  277. }
  278. extern std::ostream out(std::cout.rdbuf());
  279. SimpleLogger* newlogger;
  280. /// functions declarations
  281. //////////////////////////////////////////////////////////////
  282. void get_API_version (CActiveSocket& SocketActive);
  283. void get_sw_revision(CActiveSocket& SocketActive);
  284. void get_gru_state(CActiveSocket& SocketActive);
  285. void turn_ps_on(CActiveSocket& SocketActive);
  286. void turn_ps_off(CActiveSocket& SocketActive);
  287. void socket_close(CActiveSocket SocketActive);
  288. vector <int32_t> get_unloaded_num(vector<int32_t> segment_status);
  289. void upload_traj(CActiveSocket& SocketActive, vector<vector<int32_t>> nodes);
  290. vector <int32_t> download_traject (CActiveSocket &SocketActive, int32_t points_cnt);
  291. vector<vector<int32_t>> get_nodes(const string& Traject_file_name);
  292. string hex_converting(int num);
  293. //////////////////////////////////////////////////////////////
  294. /// request functions
  295. //////////////////////////////////////////////////////////////
  296. namespace request
  297. {
  298. const float MAX_IFB_AMPL = 151.0f;
  299. constexpr size_t MAX_PACKET{4096};
  300. const int32_t NODES_PER_PACKET{200}; // Number of points for 1 package
  301. const uint32_t PACKETS_WO_CONFIRM{1}; // How many packages could be sent without confirmation
  302. const double CONFIRM_TIMEOUT_SEC{0.1};
  303. const int32_t POINTS_PER_PACKET{500};
  304. string hex_converting(int32_t num)
  305. {
  306. stringstream mystream;
  307. mystream << hex << num;
  308. if(num < 0)
  309. {
  310. return mystream.str().substr(4);
  311. }
  312. else
  313. {
  314. return mystream.str();
  315. }
  316. }
  317. void ShowError(CSimpleSocket ss, string s)
  318. {
  319. *(newlogger) << " " << s << " : " << " = " << ss.DescribeError() << '\n';
  320. *(newlogger) << " IsSocketValid() = " << ss.IsSocketValid() << '\n';
  321. } //ShowError
  322. void device_reset(CActiveSocket& SocketActive)
  323. {
  324. uint8 buf[MAX_PACKET] ;
  325. buf[0] = uint8(0xAA);
  326. buf[1] = uint8(0xAA);
  327. buf[2] = uint8(0x01);
  328. buf[3] = uint8(0x00);
  329. *(newlogger) << "DEVICE RESET";
  330. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf, 4) << '\n';
  331. ShowError(SocketActive, "SocketActive.Send");
  332. /// @return number of bytes actually received.
  333. /// @return of zero means the connection has been shutdown on the other side.
  334. /// @return of -1 means that an error has occurred.
  335. }
  336. void error_reset(CActiveSocket& SocketActive)
  337. {
  338. uint8 buf[MAX_PACKET] ;
  339. buf[0] = uint8(0xAA);
  340. buf[1] = uint8(0xAA);
  341. buf[2] = uint8(0x02);
  342. buf[3] = uint8(0x00);
  343. *(newlogger) << "DEVICE RESET";
  344. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf, 4) << '\n';
  345. ShowError(SocketActive, "SocketActive.Send");
  346. /// @return number of bytes actually received.
  347. /// @return of zero means the connection has been shutdown on the other side.
  348. /// @return of -1 means that an error has occurred.
  349. }
  350. void get_API_version (CActiveSocket& SocketActive){ //This function send API version request and shows response
  351. uint8 buf[MAX_PACKET] ;
  352. buf[0] = uint8(0xAA);
  353. buf[1] = uint8(0xAA);
  354. buf[2] = uint8(0x0C);
  355. buf[3] = uint8(0x00);
  356. *(newlogger) << "GET API VERSION";
  357. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf, 4) << '\n';
  358. ShowError(SocketActive, "SocketActive.Send");
  359. *(newlogger) << "listening..." << '\n';
  360. *(newlogger) << "SocketActive.Receive = " << hex <<SocketActive.Receive(MAX_PACKET, buf) << '\n';
  361. ShowError(SocketActive, "SocketActive.Receive");
  362. /// @return number of bytes actually received.
  363. /// @return of zero means the connection has been shutdown on the other side.
  364. /// @return of -1 means that an error has occurred.
  365. stringstream ss;
  366. for(int32_t i=0; i<SocketActive.GetBytesReceived(); i++)
  367. {
  368. //cout << " buf[" << ii << "] = " << buf[ii] << " " << endl;
  369. ss << hex << buf[i];
  370. } //for
  371. *(newlogger) << "Bytes recieved: " << ss.str() << '\n';
  372. decode_get_api_version(buf,SocketActive.GetBytesReceived());
  373. }// get_API_version
  374. void get_sw_revision(CActiveSocket& SocketActive){ //This function send revision version request and shows response
  375. uint8 buf[MAX_PACKET] ;
  376. buf[0] = uint8(0xAA);
  377. buf[1] = uint8(0xAA);
  378. buf[2] = uint8(0x0D);
  379. buf[3] = uint8(0x00);
  380. *(newlogger) << "GET SW REVISION";
  381. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf, 4) << '\n';
  382. ShowError(SocketActive, "SocketActive.Send");
  383. *(newlogger) << "listening..." << '\n';
  384. *(newlogger) << "SocketActive.Receive = " << hex <<SocketActive.Receive(MAX_PACKET, buf) << '\n';
  385. ShowError(SocketActive, "SocketActive.Receive");
  386. /// @return number of bytes actually received.
  387. /// @return of zero means the connection has been shutdown on the other side.
  388. /// @return of -1 means that an error has occurred.
  389. stringstream ss;
  390. for(int32_t ii=0; ii<SocketActive.GetBytesReceived(); ii++)
  391. {
  392. //cout << " buf[" << ii << "] = " << buf[ii] << " " << endl;
  393. ss << hex << buf[ii];
  394. } //for
  395. *(newlogger) << "Bytes Received : " << ss.str() << '\n' << endl;
  396. decode_get_sw_revision(buf, SocketActive.GetBytesReceived());
  397. }//get_sw_revision
  398. void get_gru_state(CActiveSocket& SocketActive){ //This function send request of state gradient amplifier and shows response
  399. uint8 buf[MAX_PACKET] ;
  400. buf[0] = uint8(0xAA);
  401. buf[1] = uint8(0xAA);
  402. buf[2] = uint8(0x05);
  403. buf[3] = uint8(0x00);
  404. *(newlogger) << "GET GRU STATE";
  405. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf, 4) << '\n';
  406. ShowError(SocketActive, "SocketActive.Send");
  407. *(newlogger) << "listening..." << '\n';
  408. *(newlogger) << "SocketActive.Receive = " << hex <<SocketActive.Receive(MAX_PACKET, buf) << '\n';
  409. ShowError(SocketActive, "SocketActive.Receive");
  410. /// @return number of bytes actually received.
  411. /// @return of zero means the connection has been shutdown on the other side.
  412. /// @return of -1 means that an error has occurred.
  413. stringstream ss;
  414. for(int32_t ii=0; ii<SocketActive.GetBytesReceived(); ii++)
  415. {
  416. //cout << " buf[" << ii << "] = " << buf[ii] << " " << endl;
  417. ss << hex << buf[ii];
  418. } //for
  419. *(newlogger) << "Bytes Received : " << ss.str() << '\n' << endl;
  420. decode_get_gru_state(buf, SocketActive.GetBytesReceived());
  421. } //get_gru_state
  422. void turn_ps_on(CActiveSocket& SocketActive){
  423. uint8 buf[MAX_PACKET] ;
  424. buf[0] = uint8(0xAA);
  425. buf[1] = uint8(0xAA);
  426. buf[2] = uint8(0x03);
  427. buf[3] = uint8(0x00);
  428. *(newlogger) << "TURN PS ON";
  429. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf, 4) << '\n';
  430. ShowError(SocketActive, "SocketActive.Send");
  431. *(newlogger) << "listening..." << '\n';
  432. //*(newlogger) << "SocketActive.Receive = " << hex <<SocketActive.Receive(MAX_PACKET, buf) << '\n';
  433. //ShowError(SocketActive, "SocketActive.Receive");
  434. stringstream ss;
  435. //for(int32_t ii=0; ii<SocketActive.GetBytesReceived(); ii++)
  436. //{
  437. //cout << " buf[" << ii << "] = " << buf[ii] << " " << endl;
  438. //ss << hex << buf[ii];
  439. //} //for
  440. //*(newlogger) << "Bytes Received : " << ss.str() << '\n';
  441. }
  442. void turn_ps_off(CActiveSocket& SocketActive){
  443. uint8 buf[MAX_PACKET] ;
  444. buf[0] = uint8(0xAA);
  445. buf[1] = uint8(0xAA);
  446. buf[2] = uint8(0x04);
  447. buf[3] = uint8(0x00);
  448. *(newlogger) << "TURN PS OFF";
  449. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf, 4) << '\n';
  450. ShowError(SocketActive, "SocketActive.Send");
  451. *(newlogger) << "listening..." << '\n';
  452. //*(newlogger) << "SocketActive.Receive = " << hex <<SocketActive.Receive(MAX_PACKET, buf) << '\n';
  453. //ShowError(SocketActive, "SocketActive.Receive");
  454. stringstream ss;
  455. //for(int32_t ii=0; ii<SocketActive.GetBytesReceived(); ii++)
  456. // {
  457. //cout << " buf[" << ii << "] = " << buf[ii] << " " << endl;
  458. // ss << hex << buf[ii];
  459. //} //for
  460. //*(newlogger) << "Bytes Received : " << ss.str() << '\n';
  461. }
  462. void socket_close(CActiveSocket SocketActive){ // This function closes socket
  463. *(newlogger) << "SocketActive.Close() = " << SocketActive.Close() << '\n';
  464. ShowError(SocketActive, "SocketActive.Close");
  465. *(newlogger) << "closed" << '\n';
  466. }
  467. vector<vector<int32_t>> get_nodes(const string& Traject_file_name) {
  468. vector<vector<int32_t>> nodes;
  469. ifstream myfile(Traject_file_name);
  470. if (!myfile.is_open()) { // check if file is open
  471. *(newlogger) << LogPref::Flag(ERROR) << "Unable to open file\n";
  472. }
  473. int32_t num1, num2;
  474. while(myfile >> num1 >> num2) {
  475. nodes.push_back({num1, num2});
  476. }
  477. return nodes;
  478. }//get nodes
  479. vector <int32_t> get_unloaded_num(vector<int32_t> segment_status){
  480. vector <int32_t> res;
  481. for (uint32_t i = 0; i< segment_status.size();i++){
  482. if (segment_status[i] != 0){
  483. res.push_back(i);
  484. }
  485. }
  486. return res;
  487. }//get_unloaded_num
  488. //function to upload a segment of traject
  489. void upload_segment(CActiveSocket &SocketActive, int32_t seg_num, bool need_confirm, vector<vector<int32_t>> nodes)
  490. {
  491. int32_t counter=0;
  492. uint8 buf[MAX_PACKET]{0};
  493. string str1 = hex_converting(seg_num);
  494. buf[0] = uint8(0xAA);
  495. buf[1] = uint8(0xAA);
  496. buf[2] = uint8(0x07);
  497. buf[3] = uint8(0x00);
  498. counter+=4;
  499. //data of segment traject
  500. need_confirm = true;
  501. if(need_confirm)
  502. {
  503. buf[4] = uint8(stoi(str1, nullptr, 16));
  504. buf[5] = uint8(0x80);
  505. counter+=2;
  506. }
  507. else{
  508. buf[4] = uint8(stoi(str1, nullptr, 16));
  509. counter++;
  510. }
  511. int32_t NULL32=0;
  512. int32_t NODES_SIZE = nodes.size();
  513. int32_t first_node_idx = max( seg_num * NODES_PER_PACKET - seg_num, NULL32 );
  514. int32_t last_node_idx = min( first_node_idx + NODES_PER_PACKET, NODES_SIZE) - 1;
  515. int32_t nodes_in_this_packet = last_node_idx - first_node_idx + 1;
  516. string str2 = hex_converting(nodes_in_this_packet);
  517. buf[counter++] = uint8(stoi(str2, nullptr, 16));
  518. buf[counter++] = uint8(0x00);
  519. for(int i = first_node_idx; i <last_node_idx+1; i++)
  520. {
  521. string hexString1 = hex_converting(nodes[i][0]);
  522. uint32_t tempcounter = counter;
  523. string temp1, temp2;
  524. for(int j = hexString1.length()-1; j > 0; j = j - 2)
  525. {
  526. buf[tempcounter++] = uint8(stoi(hexString1.substr(j-1,2), nullptr, 16) );
  527. }
  528. if(hexString1.length() % 2 != 0)
  529. {
  530. temp1 = hexString1[0];
  531. hexString1.erase(0);
  532. buf[tempcounter++] = uint8(stoi(temp1, nullptr, 16) );
  533. }
  534. counter+=4;
  535. uint32_t tempcounter2 = counter;
  536. string hexString2 = hex_converting(nodes[i][1]);
  537. for(int j = hexString2.length()-1; j > 0; j -= 2)
  538. {
  539. buf[tempcounter2++] = uint8(stoi(hexString2.substr(j-1,2), nullptr, 16) );
  540. }
  541. if(hexString2.length() % 2 != 0)
  542. {
  543. temp2 = hexString2[0];
  544. hexString1.erase(0);
  545. buf[tempcounter2++] = uint8(stoi(temp2, nullptr, 16) );
  546. }
  547. counter+=2;
  548. }
  549. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf, counter) << '\n';
  550. ShowError(SocketActive, "SocketActive.Send");
  551. }
  552. void switch_func (string hexString, int32_t& counter, uint8 (&buf)[MAX_PACKET]){
  553. int tempcounter = counter;
  554. string temp1;
  555. for(int j = hexString.length()-1; j > 0; j=j-2)
  556. {
  557. buf[tempcounter++] = uint8(stoi(hexString.substr(j-1,2), nullptr, 16) );
  558. }
  559. if(hexString.length() % 2 != 0)
  560. {
  561. temp1 = hexString[0];
  562. hexString.erase(0);
  563. buf[tempcounter++] = uint8(stoi(temp1, nullptr, 16) );
  564. }
  565. }
  566. void upload_traj(CActiveSocket& SocketActive, vector<vector<int32_t>> nodes){
  567. //This function send trajectory to gradient amplifier
  568. int32_t counter = 0;
  569. uint8 buf[MAX_PACKET]{0} ;
  570. buf[0] = uint8(0xAA);
  571. buf[1] = uint8(0xAA);
  572. buf[2] = uint8(0x06);
  573. buf[3] = uint8(0x00);
  574. counter+=4;
  575. string hexString = hex_converting(nodes.size());
  576. string hexString2 = hex_converting(nodes[nodes.size()-1][0]);
  577. switch_func(hexString2, counter, buf);
  578. counter+=4;
  579. switch_func(hexString, counter, buf);
  580. counter+=4;
  581. *(newlogger) << "UPLOADING TRAJECTORY";
  582. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf, 12) << '\n';
  583. ShowError(SocketActive, "SocketActive.Send");
  584. int32_t nodes_cnt = nodes.size();
  585. int32_t segments_cnt = nodes_cnt / NODES_PER_PACKET; // segments_count
  586. if (nodes_cnt % NODES_PER_PACKET != 0)
  587. segments_cnt += 1;
  588. vector<int32_t> segment_status(segments_cnt); //���������� �� ���������
  589. segment_status.assign(segments_cnt, -2);
  590. int32_t left_wo_confirm{PACKETS_WO_CONFIRM};
  591. //bool confirm_timeout_detected = false;
  592. //string prev_debug_info = " ";
  593. vector <int32_t> uploaded_nums;
  594. uploaded_nums = get_unloaded_num(segment_status);
  595. int32_t counter_uploaded_nums = uploaded_nums.size()-1;
  596. while (!uploaded_nums.empty()){
  597. int32_t seg_num;
  598. seg_num = uploaded_nums.front();
  599. if (segment_status[seg_num] != -2){
  600. *(newlogger) << "Repeating upload segment" << seg_num << "with status" <<segment_status[seg_num] << '\n';
  601. }//if
  602. bool need_confirm = false; //by default
  603. if (left_wo_confirm == 0)
  604. {
  605. left_wo_confirm = PACKETS_WO_CONFIRM;
  606. need_confirm = true;
  607. }
  608. else left_wo_confirm -= 1; //for next iteration
  609. if (seg_num == counter_uploaded_nums)
  610. need_confirm = true;
  611. upload_segment(SocketActive, seg_num, need_confirm, nodes);
  612. *(newlogger) << "listening..." << '\n\n';
  613. *(newlogger) << "SocketActive.Receive = " << hex <<SocketActive.Receive(MAX_PACKET, buf) << '\n';
  614. ShowError(SocketActive, "SocketActive.Receive");
  615. if(int32_t(buf[4]) == seg_num + 1)
  616. {
  617. uploaded_nums.erase(uploaded_nums.begin());
  618. *(newlogger) <<"Uploaded: " << seg_num + 1 << '\n';
  619. }
  620. else
  621. {
  622. *(newlogger) << LogPref::Flag(ERROR) << "Fatal error 404" << '\n';
  623. }
  624. }//while
  625. uint8 buf_eot[MAX_PACKET]{0};
  626. buf_eot[0] = 0xAA;
  627. buf_eot[1] = 0xAA;
  628. buf_eot[2] = 0x08;
  629. buf_eot[3] = 0x00;
  630. ;
  631. *(newlogger) << "UPLOADING TRAJECTORY";
  632. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf_eot, 4) << '\n';
  633. ShowError(SocketActive, "SocketActive.Send");
  634. }//upload_traj
  635. void download_traject (CActiveSocket &SocketActive, int32_t points_cnt)
  636. {
  637. int32_t counter=0;
  638. vector<int32_t> points;
  639. uint8 buf[MAX_PACKET]{0} ;
  640. buf[0] = uint8(0xAA);
  641. buf[1] = uint8(0xAA);
  642. buf[2] = uint8(0x09);
  643. buf[3] = uint8(0x00);
  644. buf[4] = uint8(0x00);
  645. buf[5] = uint8(0x00);
  646. buf[6] = uint8(0x00);
  647. buf[7] = uint8(0x00);
  648. counter+=8;
  649. switch_func(hex_converting(points_cnt), counter, buf);
  650. *(newlogger) << "DOWNLOADING TRAJECTORY" << endl;
  651. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf, 12) << '\n';
  652. ShowError(SocketActive, "SocketActive.Send");
  653. uint32_t expected_packets_cnt = points_cnt / POINTS_PER_PACKET;
  654. if (points_cnt % POINTS_PER_PACKET != 0)
  655. {
  656. expected_packets_cnt += 1;
  657. }
  658. vector<int32_t> downloaded_segments;
  659. downloaded_segments.assign(expected_packets_cnt, 0);
  660. points.assign(points_cnt, 0);
  661. int32_t for_cnt=0;
  662. int32_t skiped_nums;
  663. FILE *file;
  664. char filename[] = "downloaded_traj.txt";
  665. file = fopen(filename, "w");
  666. if (file == NULL)
  667. {
  668. printf("Error\n", filename);
  669. }
  670. int null_counter=0;
  671. while(!downloaded_segments.empty())
  672. {
  673. skiped_nums = for_cnt == 0 ? 10 : 12;
  674. for_cnt++;
  675. downloaded_segments.pop_back();
  676. *(newlogger) << "listening..." << '\n';
  677. *(newlogger) << "SocketActive.Receive = " << hex <<SocketActive.Receive(MAX_PACKET, buf) << '\n';
  678. ShowError(SocketActive, "SocketActive.Receive");
  679. for(int32_t ii=10; ii<SocketActive.GetBytesReceived(); ii+=2)
  680. {
  681. fprintf(file, "%d\n", int16_t(buf[ii+1] << 8 | buf[ii])) ;
  682. } //for
  683. }
  684. fclose(file);
  685. }
  686. void request_current (CActiveSocket &SocketActive, int32_t points_cnt)
  687. {
  688. int32_t counter=0;
  689. vector<int32_t> points;
  690. uint8 buf[MAX_PACKET]{0} ;
  691. buf[0] = uint8(0xAA);
  692. buf[1] = uint8(0xAA);
  693. buf[2] = uint8(0x0A);
  694. buf[3] = uint8(0x00);
  695. buf[4] = uint8(0x00);
  696. buf[5] = uint8(0x00);
  697. buf[6] = uint8(0x00);
  698. buf[7] = uint8(0x00);
  699. counter+=8;
  700. switch_func(hex_converting(points_cnt), counter, buf);
  701. *(newlogger) << "DOWNLOADING CURRENT" << endl;
  702. *(newlogger) << "SocketActive.Send = " << SocketActive.Send(buf, 12) << '\n';
  703. ShowError(SocketActive, "SocketActive.Send");
  704. uint32_t expected_packets_cnt = points_cnt / POINTS_PER_PACKET;
  705. if (points_cnt % POINTS_PER_PACKET != 0)
  706. {
  707. expected_packets_cnt += 1;
  708. }
  709. points.assign(points_cnt, 0);
  710. int32_t for_cnt=0;
  711. int32_t skiped_nums;
  712. FILE *file;
  713. char filename[] = "downloaded_current.txt";
  714. file = fopen(filename, "w");
  715. if (file == NULL)
  716. {
  717. printf("Error\n", filename);
  718. }
  719. *(newlogger) << "Points expected: " << std::dec << points_cnt << endl;
  720. *(newlogger) << "Points per packet: " << std::dec << expected_packets_cnt << endl;
  721. while(expected_packets_cnt != 0)
  722. {
  723. expected_packets_cnt--;
  724. *(newlogger) << "listening..." << '\n';
  725. *(newlogger) << "SocketActive.Receive = " << hex <<SocketActive.Receive(MAX_PACKET, buf) << '\n';
  726. ShowError(SocketActive, "SocketActive.Receive");
  727. for(int32_t ii=10; ii<SocketActive.GetBytesReceived(); ii+=2)
  728. {
  729. int16_t current_value;
  730. memcpy(&current_value, buf + ii, 2);
  731. fprintf(file, "%f\n", current_value * (MAX_IFB_AMPL / 32768));
  732. } //for
  733. }
  734. fclose(file);
  735. }
  736. } //namespace request
  737. //////////////////////////////////////////////////////////////
  738. int main(int argc, char** argv)
  739. {
  740. newlogger = new SimpleLogger(out, "gra", std::string("gralogs-cmd"));
  741. if(argc > 1)
  742. {
  743. if(strcmp(argv[1], "--debug") == 0)
  744. {
  745. newlogger->enableConsoleOutput(true);
  746. }
  747. else {
  748. newlogger->enableConsoleOutput(false);
  749. }
  750. }
  751. string Traject_file_name;
  752. /*
  753. if(argc >= 3)
  754. Traject_file_name = argv[1];
  755. else
  756. {
  757. *(newlogger) << LogPref::Flag(ERROR) << "Wrong arguments!";
  758. return -1;
  759. }
  760. */
  761. *(newlogger) << "Sync delay: 450 msec" << endl;
  762. delay(450);
  763. string addr;
  764. cout << "Enter IP address: ";
  765. getline(cin, addr);
  766. SetConsoleCP(866);
  767. SetConsoleOutputCP(866);
  768. int32_t points_cnt = 0;
  769. CActiveSocket SocketActive( CSimpleSocket::CSocketType::SocketTypeUdp) ;
  770. *(newlogger) << "starting" << endl;
  771. // Initialize our socket object
  772. *(newlogger) << "SocketActive.Initialize = " << SocketActive.Initialize() << endl;
  773. request::ShowError(SocketActive, "SocketActive.Initialize");
  774. *(newlogger) << "SocketActive.Open = " << SocketActive.Open(addr.c_str(), 5002) << '\n';
  775. request::ShowError(SocketActive, "SocketActive.Open");
  776. cout << "\n" << "Command list: \n \n";
  777. cout << "a - get_api_version \n";
  778. cout << "v - get_sw_revision \n";
  779. cout << "s - get_gru_state \n";
  780. cout << "1 - turn_ps_on \n";
  781. cout << "0 - turn_ps_off \n";
  782. cout << "d <points> - download_traject \n";
  783. cout << "u <file_name> - upload_traj \n";
  784. cout << "q - socket_close and exit \n \n";
  785. bool exit = false;
  786. Traject_file_name = "";
  787. while(!exit) {
  788. string cmd;
  789. cout << "Enter command: ";
  790. delay(100);
  791. getline(cin, cmd, '\n');
  792. *(newlogger) << "Command: " << cmd << endl;
  793. stringstream ss(cmd);
  794. string arg;
  795. getline(ss, arg, ' ');
  796. getline(ss, arg, ' ');
  797. switch(cmd[0])
  798. {
  799. case 'a':
  800. request::get_API_version(SocketActive);
  801. break;
  802. case 'v':
  803. request::get_sw_revision(SocketActive);
  804. break;
  805. case 's':
  806. request::get_gru_state(SocketActive);
  807. break;
  808. case '1':
  809. request::turn_ps_on(SocketActive);
  810. break;
  811. case '0':
  812. request::turn_ps_off(SocketActive);
  813. break;
  814. case 'd':
  815. {
  816. cout << "Downloading traject..." << endl;
  817. int points;
  818. try
  819. {
  820. points = stoi(arg);
  821. }
  822. catch(invalid_argument e)
  823. {
  824. cout << "Exception: " << e.what() << endl;
  825. break;
  826. }
  827. request::download_traject(SocketActive, points);
  828. break;
  829. }
  830. case 'u':
  831. {
  832. cout << "Uploading trajectory..." << endl;
  833. request::upload_traj(SocketActive, request::get_nodes(arg));
  834. break;
  835. }
  836. case 'q':
  837. request::socket_close(SocketActive);
  838. exit = true;
  839. break;
  840. case 'r':
  841. cout << "Reset device." << endl;
  842. request::device_reset(SocketActive);
  843. break;
  844. case 'e':
  845. cout << "Reset error." << endl;
  846. request::error_reset(SocketActive);
  847. break;
  848. case 'c':
  849. {
  850. cout << "Downloading currents..." << endl;
  851. int points;
  852. try
  853. {
  854. points = stoi(arg);
  855. }
  856. catch(invalid_argument e)
  857. {
  858. cout << "Exception: " << e.what() << endl;
  859. break;
  860. }
  861. request::request_current(SocketActive, points);
  862. break;
  863. }
  864. default:
  865. cout << "Unknown command" << endl;
  866. break;
  867. }
  868. }
  869. newlogger->closeLogger();
  870. return 0;
  871. }//main