55
66#include " sweep.h"
77
8+ #include < algorithm>
89#include < chrono>
910#include < exception>
1011#include < string>
@@ -19,13 +20,25 @@ struct sweep_error {
1920
2021#define SWEEP_MAX_SAMPLES 4096
2122
23+ struct sample {
24+ int32_t angle; // in millidegrees
25+ int32_t distance; // in cm
26+ int32_t signal_strength; // range 0:255
27+ };
28+
2229struct sweep_scan {
23- int32_t angle[SWEEP_MAX_SAMPLES]; // in millidegrees
24- int32_t distance[SWEEP_MAX_SAMPLES]; // in cm
25- int32_t signal_strength[SWEEP_MAX_SAMPLES]; // range 0:255
30+ sample samples[SWEEP_MAX_SAMPLES];
2631 int32_t count;
2732};
2833
34+ static sample parse_payload (const sweep::protocol::response_scan_packet_s& msg) {
35+ sample ret;
36+ ret.angle = msg.get_angle_millideg ();
37+ ret.distance = msg.distance ;
38+ ret.signal_strength = msg.signal_strength ;
39+ return ret;
40+ }
41+
2942struct sweep_device {
3043 sweep::serial::device_s serial; // serial port communication
3144 bool is_scanning;
@@ -88,36 +101,31 @@ static void sweep_device_accumulate_scans(sweep_device_s device) try {
88101 SWEEP_ASSERT (device);
89102 SWEEP_ASSERT (device->is_scanning );
90103
91- sweep::protocol::response_scan_packet_s responses [SWEEP_MAX_SAMPLES];
104+ sample buffer [SWEEP_MAX_SAMPLES];
92105 int32_t received = 0 ;
93106
94107 while (!device->stop_thread && received < SWEEP_MAX_SAMPLES) {
95- sweep::protocol::read_response_scan (device->serial , &responses[received]);
96108
97- const bool is_sync = responses[received].sync_error & sweep::protocol::response_scan_packet_sync::sync;
98- const bool has_error = (responses[received].sync_error >> 1 ) != 0 ; // shift out sync bit, others are errors
109+ const auto response = sweep::protocol::read_response_scan (device->serial );
99110
100- if (!has_error) {
111+ if (!response.has_error ()) {
112+ buffer[received] = parse_payload (response);
101113 received++;
102114 }
103115
104- if (is_sync) {
105- if (received <= 1 )
106- continue ;
116+ if (response.is_sync () && received > 1 ) {
117+
107118 // package the previous scan without the sync reading from the subsequent scan
108119 auto out = std::unique_ptr<sweep_scan>(new sweep_scan);
109120 out->count = received - 1 ; // minus 1 to exclude sync reading
110- for (int32_t it = 0 ; it < received - 1 ; ++it) {
111- out->angle [it] = sweep::protocol::angle_raw_to_millideg (responses[it].angle );
112- out->distance [it] = responses[it].distance ;
113- out->signal_strength [it] = responses[it].signal_strength ;
114- }
121+
122+ std::copy_n (std::begin (buffer), received - 1 , std::begin (out->samples ));
115123
116124 // place the scan in the queue
117125 device->scan_queue .enqueue ({std::move (out), nullptr });
118126
119127 // place the sync reading at the start for the next scan
120- responses [0 ] = responses [received - 1 ];
128+ buffer [0 ] = buffer [received - 1 ];
121129
122130 // reset received
123131 received = 1 ;
@@ -140,8 +148,7 @@ static void sweep_device_attempt_start_scanning(sweep_device_s device, sweep_err
140148
141149 sweep::protocol::write_command (device->serial , sweep::protocol::DATA_ACQUISITION_START);
142150
143- sweep::protocol::response_header_s response;
144- sweep::protocol::read_response_header (device->serial , sweep::protocol::DATA_ACQUISITION_START, &response);
151+ auto response = sweep::protocol::read_response_header (device->serial , sweep::protocol::DATA_ACQUISITION_START);
145152
146153 // Check the status bytes do not indicate failure
147154 const uint8_t status_bytes[2 ] = {response.cmdStatusByte1 , response.cmdStatusByte2 };
@@ -172,8 +179,7 @@ static void sweep_device_attempt_set_motor_speed(sweep_device_s device, int32_t
172179
173180 sweep::protocol::write_command_with_arguments (device->serial , sweep::protocol::MOTOR_SPEED_ADJUST, args);
174181
175- sweep::protocol::response_param_s response;
176- sweep::protocol::read_response_param (device->serial , sweep::protocol::MOTOR_SPEED_ADJUST, &response);
182+ const auto response = sweep::protocol::read_response_param (device->serial , sweep::protocol::MOTOR_SPEED_ADJUST);
177183
178184 // Check the status bytes do not indicate failure
179185 const uint8_t status_bytes[2 ] = {response.cmdStatusByte1 , response.cmdStatusByte2 };
@@ -288,9 +294,8 @@ void sweep_device_stop_scanning(sweep_device_s device, sweep_error_s* error) try
288294 // Read the response from the first stop command
289295 // It is possible this will contain garbage bytes (leftover from data stream), and will error
290296 // But we are guaranteed to read at least as many bytes as the length of a stop response
291- sweep::protocol::response_header_s garbage_response;
292297 try {
293- sweep::protocol::read_response_header (device->serial , sweep::protocol::DATA_ACQUISITION_STOP, &garbage_response );
298+ sweep::protocol::read_response_header (device->serial , sweep::protocol::DATA_ACQUISITION_STOP);
294299 } catch (const std::exception& ignore) {
295300 // Catch and ignore the error in the case of the stop response containing garbage bytes
296301 // Occurs if the device was actively streaming data before the stop cmd
@@ -304,8 +309,7 @@ void sweep_device_stop_scanning(sweep_device_s device, sweep_error_s* error) try
304309 sweep::protocol::write_command (device->serial , sweep::protocol::DATA_ACQUISITION_STOP);
305310
306311 // read the response
307- sweep::protocol::response_header_s response;
308- sweep::protocol::read_response_header (device->serial , sweep::protocol::DATA_ACQUISITION_STOP, &response);
312+ sweep::protocol::read_response_header (device->serial , sweep::protocol::DATA_ACQUISITION_STOP);
309313
310314 device->is_scanning = false ;
311315} catch (const std::exception& e) {
@@ -338,8 +342,7 @@ bool sweep_device_get_motor_ready(sweep_device_s device, sweep_error_s* error) t
338342
339343 sweep::protocol::write_command (device->serial , sweep::protocol::MOTOR_READY);
340344
341- sweep::protocol::response_info_motor_ready_s response;
342- sweep::protocol::read_response_info_motor_ready (device->serial , sweep::protocol::MOTOR_READY, &response);
345+ const auto response = sweep::protocol::read_response_info_motor_ready (device->serial );
343346
344347 int32_t ready_code = sweep::protocol::ascii_bytes_to_integral (response.motor_ready );
345348 SWEEP_ASSERT (ready_code >= 0 );
@@ -357,8 +360,7 @@ int32_t sweep_device_get_motor_speed(sweep_device_s device, sweep_error_s* error
357360
358361 sweep::protocol::write_command (device->serial , sweep::protocol::MOTOR_INFORMATION);
359362
360- sweep::protocol::response_info_motor_speed_s response;
361- sweep::protocol::read_response_info_motor_speed (device->serial , sweep::protocol::MOTOR_INFORMATION, &response);
363+ const auto response = sweep::protocol::read_response_info_motor_speed (device->serial );
362364
363365 int32_t speed = sweep::protocol::ascii_bytes_to_integral (response.motor_speed );
364366 SWEEP_ASSERT (speed >= 0 );
@@ -391,8 +393,7 @@ int32_t sweep_device_get_sample_rate(sweep_device_s device, sweep_error_s* error
391393
392394 sweep::protocol::write_command (device->serial , sweep::protocol::SAMPLE_RATE_INFORMATION);
393395
394- sweep::protocol::response_info_sample_rate_s response;
395- sweep::protocol::read_response_info_sample_rate (device->serial , sweep::protocol::SAMPLE_RATE_INFORMATION, &response);
396+ const auto response = sweep::protocol::read_response_info_sample_rate (device->serial );
396397
397398 // 01: 500-600Hz, 02: 750-800Hz, 03: 1000-1050Hz
398399 int32_t code = sweep::protocol::ascii_bytes_to_integral (response.sample_rate );
@@ -446,8 +447,7 @@ void sweep_device_set_sample_rate(sweep_device_s device, int32_t hz, sweep_error
446447
447448 sweep::protocol::write_command_with_arguments (device->serial , sweep::protocol::SAMPLE_RATE_ADJUST, args);
448449
449- sweep::protocol::response_param_s response;
450- sweep::protocol::read_response_param (device->serial , sweep::protocol::SAMPLE_RATE_ADJUST, &response);
450+ const auto response = sweep::protocol::read_response_param (device->serial , sweep::protocol::SAMPLE_RATE_ADJUST);
451451
452452 // Check the status bytes do not indicate failure
453453 const uint8_t status_bytes[2 ] = {response.cmdStatusByte1 , response.cmdStatusByte2 };
@@ -474,21 +474,21 @@ int32_t sweep_scan_get_angle(sweep_scan_s scan, int32_t sample) {
474474 SWEEP_ASSERT (scan);
475475 SWEEP_ASSERT (sample >= 0 && sample < scan->count && " sample index out of bounds" );
476476
477- return scan->angle [sample];
477+ return scan->samples [sample]. angle ;
478478}
479479
480480int32_t sweep_scan_get_distance (sweep_scan_s scan, int32_t sample) {
481481 SWEEP_ASSERT (scan);
482482 SWEEP_ASSERT (sample >= 0 && sample < scan->count && " sample index out of bounds" );
483483
484- return scan->distance [sample];
484+ return scan->samples [sample]. distance ;
485485}
486486
487487int32_t sweep_scan_get_signal_strength (sweep_scan_s scan, int32_t sample) {
488488 SWEEP_ASSERT (scan);
489489 SWEEP_ASSERT (sample >= 0 && sample < scan->count && " sample index out of bounds" );
490490
491- return scan->signal_strength [sample];
491+ return scan->samples [sample]. signal_strength ;
492492}
493493
494494void sweep_scan_destruct (sweep_scan_s scan) {
0 commit comments