4
4
#include < mutex>
5
5
6
6
#include " BufferedSerial.h"
7
- #include " events/EventQueue.h"
8
7
#include " events/Event.h"
8
+ #include " events/EventQueue.h"
9
9
10
10
#include " umiusi/inputs.hpp"
11
11
#include " umiusi/outputs.hpp"
12
+ #include " umiusi/trylock_guard.hpp"
12
13
13
14
using namespace std ::chrono_literals;
14
15
@@ -20,6 +21,7 @@ int main() {
20
21
CachedInputs inputs{};
21
22
OutputMachine output{};
22
23
mbed::BufferedSerial pc (USBTX, USBRX);
24
+ rtos::Mutex pc_mutex{};
23
25
std::atomic_bool received_order;
24
26
pc.set_blocking (false );
25
27
inputs.read ();
@@ -34,58 +36,62 @@ int main() {
34
36
output.suspend ();
35
37
}));
36
38
37
- const auto process_order = [&pc, &inputs, &output, &initialize_event, &suspend_event](std::uint8_t header) {
39
+ auto write_order_event = equeue.event (mbed::callback ([&pc, &pc_mutex, &output]() {
40
+ std::lock_guard<rtos::Mutex> _guard (pc_mutex);
41
+ std::array<uint8_t , 16 > buffer{}; // FIXME: 16 == THRUSTER_NUM * 2 * 2
42
+ pc.read (buffer.data (), 16 );
43
+ std::array<std::pair<uint16_t , uint16_t >, THRUSTER_NUM> pulsewidths_us{};
44
+ for (size_t i = 0 ; i < THRUSTER_NUM; ++i) {
45
+ // bldc
46
+ uint16_t pulsewidth_us_lsb = static_cast <uint16_t >(buffer[i * 2 + 0 ]);
47
+ uint16_t pulsewidth_us_msb = static_cast <uint16_t >(buffer[i * 2 + 1 ]);
48
+ pulsewidths_us[i].first = (pulsewidth_us_lsb << 0 ) | (pulsewidth_us_msb << 8 );
49
+ // servo
50
+ pulsewidth_us_lsb = static_cast <uint16_t >(buffer[i * 2 + 0 + THRUSTER_NUM * 2 ]
51
+ );
52
+ pulsewidth_us_msb = static_cast <uint16_t >(buffer[i * 2 + 1 + THRUSTER_NUM * 2 ]
53
+ );
54
+ pulsewidths_us[i].second = (pulsewidth_us_lsb << 0 )
55
+ | (pulsewidth_us_msb << 8 );
56
+ }
57
+ output.set_powers (pulsewidths_us);
58
+ }));
59
+ auto read_order_event = equeue.event (mbed::callback ([&pc, &pc_mutex, &inputs]() {
60
+ std::lock_guard<rtos::Mutex> _guard (pc_mutex);
61
+ std::array<uint8_t , 8 > buffer = inputs.get ().packet_data ();
62
+ pc.write (buffer.data (), 8 );
63
+ }));
64
+ auto read_state_order_event
65
+ = equeue.event (mbed::callback ([&pc, &pc_mutex, &output]() {
66
+ std::lock_guard<rtos::Mutex> _guard (pc_mutex);
67
+ uint8_t state_val = static_cast <uint8_t >(output.state ());
68
+ pc.write (&state_val, 1 );
69
+ }));
70
+
71
+ const auto process_order = [&write_order_event,
72
+ &read_order_event,
73
+ &read_state_order_event,
74
+ &initialize_event,
75
+ &suspend_event](std::uint8_t header) {
38
76
switch (header) {
39
- case 0 : {
40
- // write
41
- std::array<uint8_t , 16 > buffer{}; // FIXME: 16 == THRUSTER_NUM * 2 * 2
42
- pc.read (buffer.data (), 16 );
43
- std::array<std::pair<uint16_t , uint16_t >, THRUSTER_NUM> pulsewidths_us{};
44
- for (size_t i = 0 ; i < THRUSTER_NUM; ++i) {
45
- // bldc
46
- uint16_t pulsewidth_us_lsb = static_cast <uint16_t >(buffer[i * 2 + 0 ]);
47
- uint16_t pulsewidth_us_msb = static_cast <uint16_t >(buffer[i * 2 + 1 ]);
48
- pulsewidths_us[i].first = (pulsewidth_us_lsb << 0 )
49
- | (pulsewidth_us_msb << 8 );
50
- // servo
51
- pulsewidth_us_lsb
52
- = static_cast <uint16_t >(buffer[i * 2 + 0 + THRUSTER_NUM * 2 ]);
53
- pulsewidth_us_msb
54
- = static_cast <uint16_t >(buffer[i * 2 + 1 + THRUSTER_NUM * 2 ]);
55
- pulsewidths_us[i].second = (pulsewidth_us_lsb << 0 )
56
- | (pulsewidth_us_msb << 8 );
57
- }
58
- output.set_powers (pulsewidths_us);
59
- } break ;
60
- case 1 : {
61
- // read
62
- std::array<uint8_t , 8 > buffer = inputs.get ().packet_data ();
63
- pc.write (buffer.data (), 8 );
64
- } break ;
65
- case 2 : {
66
- // read state
67
- uint8_t state_val = static_cast <uint8_t >(output.state ());
68
- pc.write (&state_val, 1 );
69
- } break ;
70
- case 0xFE : {
71
- // (re)start
72
- if (output.state () == State::INITIALIZING) {
73
- return ;
74
- }
75
- initialize_event.call ();
76
- } break ;
77
- case 0xFF :
78
- // suspend
79
- suspend_event.call ();
80
- break ;
77
+ case 0 : write_order_event.call (); break ;
78
+ case 1 : read_order_event.call (); break ;
79
+ case 2 : read_state_order_event.call (); break ;
80
+ case 0xFE : initialize_event.call (); break ;
81
+ case 0xFF : suspend_event.call (); break ;
81
82
default :
82
83
// unexpected
83
84
return ;
84
85
}
85
86
};
86
- equeue.call_every (30ms, [&equeue, &pc, &received_order, &process_order]() {
87
+ // FIXME: なぜか30msより短いと挙動がおかしくなる
88
+ equeue.call_every (30ms, [&equeue, &pc, &pc_mutex, &received_order, &process_order]() {
89
+ TrylockGuard pc_guard (pc_mutex);
90
+ if (!pc_guard.locked ()) {
91
+ return ;
92
+ }
87
93
std::uint8_t header = 0 ;
88
- ssize_t res = pc.read (&header, 1 );
94
+ ssize_t res = pc.read (&header, 1 );
89
95
if (res < 1 ) {
90
96
return ;
91
97
}
0 commit comments