forked from UBC-Thunderbots/Software
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththreaded_estop_reader.cpp
More file actions
104 lines (88 loc) · 2.95 KB
/
Copy paththreaded_estop_reader.cpp
File metadata and controls
104 lines (88 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include "threaded_estop_reader.h"
#include <boost/bind/bind.hpp>
#include <thread>
#include <utility>
#include "software/logger/logger.h"
ThreadedEstopReader::ThreadedEstopReader(std::unique_ptr<UartCommunication> uart_reader)
: estop_state(EstopState::STOP),
timer(io_service, boost::posix_time::milliseconds(INTERVAL_BETWEEN_READS_MS)),
uart_reader(std::move(uart_reader))
{
estop_thread = std::thread(std::bind(&ThreadedEstopReader::continousRead, this));
}
void ThreadedEstopReader::continousRead()
{
timer.async_wait(
std::bind(&ThreadedEstopReader::tick, this, boost::asio::placeholders::error));
io_service.run();
}
bool ThreadedEstopReader::isEstopPlay()
{
return estop_state == EstopState::PLAY;
}
void ThreadedEstopReader::tick(const boost::system::error_code& error)
{
if (in_destructor)
{
timer.cancel();
}
else
{
std::vector<unsigned char> estop_msg;
try
{
uart_reader->flushSerialPort(uart_reader->flush_receive);
estop_msg = uart_reader->serialRead(ESTOP_MESSAGE_SIZE_BYTES);
}
catch (const std::exception& e)
{
LOG(FATAL)
<< "crashing system and timing out robots as we have lost connection to ESTOP source : "
<< e.what();
}
EstopState new_state;
switch (static_cast<int>(estop_msg.at(0)))
{
case ESTOP_PLAY_MSG:
{
new_state = EstopState::PLAY;
num_consecutive_status_error = 0;
break;
}
case ESTOP_STOP_MSG:
{
new_state = EstopState::STOP;
num_consecutive_status_error = 0;
break;
}
default:
{
new_state = EstopState::STATUS_ERROR;
LOG(WARNING) << "read unexpected estop message";
num_consecutive_status_error++;
break;
}
}
if (new_state != estop_state)
{
LOG(INFO) << "ESTOP changed from " << estop_state << " to " << new_state;
estop_state = new_state;
}
CHECK(num_consecutive_status_error <= MAXIMUM_CONSECUTIVE_STATUS_ERROR)
<< "ESTOP Consecutive Unexpected messages";
boost::posix_time::milliseconds next_interval(INTERVAL_BETWEEN_READS_MS);
// Reschedule the timer for interval seconds in the future:
timer.expires_from_now(next_interval);
// Posts the timer event
timer.async_wait(std::bind(&ThreadedEstopReader::tick, this,
boost::asio::placeholders::error));
}
}
ThreadedEstopReader::~ThreadedEstopReader()
{
in_destructor = true;
io_service.stop();
// We must wait for the thread to stop, as if we destroy it while it's still
// running we will segfault
estop_thread.join();
}