SerialDevice.cpp
Go to the documentation of this file.
1 #include "SerialDevice.hpp"
2 
3 #include <fcntl.h>
4 #include <termios.h>
5 
6 #include <boost/asio/write.hpp>
7 #include <boost/asio/read.hpp>
8 
9 #include <iostream>
10 #include <chrono>
11 
12 namespace
13 {
14  std::array<std::uint8_t, 4> INITIALIZE { 1, 0, 0, 0, };
15  std::array<std::uint8_t, 4> SET_POSITIONS { 2, 0, 0, 0 };
16 }
17 
18 template<typename T>
19 std::ostream &operator <<(std::ostream &o, const std::vector<T> &data)
20 {
21  for (auto it = data.cbegin(); it != data.cend(); ++it)
22  {
23  o << static_cast<int>(*it) << " ";
24  }
25  return o;
26 }
27 
28 using namespace quori_controller;
29 
31 {
32  fd_.close();
33  delete[] stateBuffer_;
34 }
35 
36 // 1538908420
37 
38 SerialDevice::Ptr SerialDevice::open(boost::asio::io_service &context, const std::string &path)
39 {
40  const int fd = ::open(path.c_str(), O_RDWR | O_NONBLOCK);
41  if (fd < 0)
42  {
43  throw std::runtime_error(strerror(errno));
44  }
45 
46  // std::cout << "Open " << path << std::endl;
47 
48  struct termios settings;
49  tcgetattr(fd, &settings);
50 
51  cfsetispeed(&settings, 115200); /* baud rate */
52  cfsetospeed(&settings, 115200); /* baud rate */
53  settings.c_cflag &= ~PARENB; /* no parity */
54  settings.c_cflag &= ~CSTOPB; /* 1 stop bit */
55  settings.c_cflag &= ~CSIZE;
56  settings.c_cflag |= CS8; /* 8 bits */
57  settings.c_cflag &= ~CRTSCTS;
58  settings.c_cflag |= CREAD | CLOCAL;
59  settings.c_iflag &= ~(IXON | IXOFF | IXANY);
60  settings.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* canonical mode */
61  settings.c_oflag &= ~OPOST; /* raw output */
62 
63  tcsetattr(fd, TCSANOW, &settings); /* apply the settings */
64  if (tcsetattr(fd, TCSAFLUSH, &settings) < 0) {
65  perror("init_serialport: Couldn't set term attributes");
66  return nullptr;
67  }
68 
69  return std::shared_ptr<SerialDevice>(new SerialDevice(boost::asio::posix::stream_descriptor(context, fd), path));
70 }
71 
72 SerialDevice::SerialDevice(boost::asio::posix::stream_descriptor &&fd, const std::string &name)
73  : fd_(std::move(fd))
74  , name_(name)
75  , numJoints_(0)
76  , stateBufferSize_(0)
77  , stateBuffer_(nullptr)
78 {
79 
80 }
81 
82 const std::string &SerialDevice::getName() const
83 {
84  return name_;
85 }
86 
88 {
89  boost::system::error_code ec;
90 
91 
92  usleep(10000UL);
94 
95 
96  std::cout << "Initialize " << name_ << std::endl;
97 
98  size_t count = write(initialize);
99 
100 
101  bool exit = false;
102  while (unprocessed_.size() < sizeof(quori::message::Initialized))
103  {
104  usleep(10000UL);
105  read();
106 
107  // std::cout << unprocessed_.size() << std::endl;
108  }
109 
110 
111  const quori::message::Initialized *const msg = reinterpret_cast<const quori::message::Initialized *>(unprocessed_.data());
112 
113  InitializationInfo ret;
114  if (strlen(msg->_0) > 0) ret.joints.push_back(InitializationInfo::JointInfo {
115  msg->_0,
116  static_cast<Joint::Mode>(msg->modes[0])
117  });
118  if (strlen(msg->_1) > 0) ret.joints.push_back(InitializationInfo::JointInfo {
119  msg->_1,
120  static_cast<Joint::Mode>(msg->modes[1])
121  });
122  if (strlen(msg->_2) > 0) ret.joints.push_back(InitializationInfo::JointInfo {
123  msg->_2,
124  static_cast<Joint::Mode>(msg->modes[2])
125  });
126 
127  unprocessed_.erase(unprocessed_.begin(), unprocessed_.begin() + sizeof(quori::message::Initialized));
128 
129 
130 
131  return ret;
132 }
133 
134 void SerialDevice::setPositions(const double *const positions, const std::size_t length)
135 {
137  msg.positions[0] = length > 0 ? positions[0] : 0;
138  msg.positions[1] = length > 1 ? positions[1] : 0;
139  msg.positions[2] = length > 2 ? positions[2] : 0;
140 
141  write(msg);
142 
143  while (unprocessed_.size() < sizeof(quori::message::SetPositionsRes))
144  {
145  read();
146  }
147 
148  auto res = *reinterpret_cast<const quori::message::SetPositionsRes *>(unprocessed_.data());
149 
150  auto seconds = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
151 
152  if (set_positions_csv_)
153  {
154  using namespace std::chrono;
155 
156  const auto time = duration_cast<microseconds>(system_clock::now().time_since_epoch());
157  set_positions_csv_->append() << name_ << time.count() << res.values[0] << res.values[1];
158  }
159 
160 
161  unprocessed_.erase(unprocessed_.begin(), unprocessed_.begin() + sizeof(quori::message::SetPositionsRes));
162 }
163 
164 void SerialDevice::set(const double *const positions, const double *const velocities, const std::size_t length)
165 {
167  msg.positions[0] = length > 0 ? positions[0] : 0;
168  msg.positions[1] = length > 1 ? positions[1] : 0;
169  msg.positions[2] = length > 2 ? positions[2] : 0;
170  msg.velocities[0] = length > 0 ? velocities[0] : 0;
171  msg.velocities[1] = length > 1 ? velocities[1] : 0;
172  msg.velocities[2] = length > 2 ? velocities[2] : 0;
173 
174  write(msg);
175 
176  while (unprocessed_.size() < sizeof(quori::message::SetPositionsRes))
177  {
178  read();
179  }
180 
181  auto res = *reinterpret_cast<const quori::message::SetPositionsRes *>(unprocessed_.data());
182  unprocessed_.erase(unprocessed_.begin(), unprocessed_.begin() + sizeof(quori::message::SetPositionsRes));
183 }
184 
186 {
188  write(msg);
189  const auto start = std::chrono::system_clock::now();
190 
191  while (unprocessed_.size() < sizeof(quori::message::States))
192  {
193  read();
194  }
195  const auto end = std::chrono::system_clock::now();
196 
197 
198 
199  state = *reinterpret_cast<const quori::message::States *>(unprocessed_.data());
200  unprocessed_.erase(unprocessed_.begin(), unprocessed_.begin() + sizeof(quori::message::States));
201 }
202 
204 {
205  std::array<std::uint8_t, 256> buffer;
206  boost::system::error_code ec;
207  size_t count = boost::asio::read(fd_, boost::asio::buffer(buffer), boost::asio::transfer_at_least(1), ec);
208  if (count == 0) return;
209 
210  unprocessed_.insert(unprocessed_.end(), buffer.begin(), buffer.begin() + count);
211 
212  while (unprocessed_.size() >= sizeof(quori::message::Log) && static_cast<quori::message::Type>(unprocessed_[0]) == quori::message::Type::Log)
213  {
214  const auto msg = reinterpret_cast<const quori::message::Log *>(unprocessed_.data());
215  std::cout << name_ << ": " << msg->message << std::endl;
216  unprocessed_.erase(unprocessed_.begin(), unprocessed_.begin() + sizeof(quori::message::Log));
217  }
218 }
219 
221 {
222  set_positions_csv_ = csv;
223  set_positions_csv_->append() << "Device" << "Time" << "M1 Sensor" << "M2 Sensor";
224 }
225 
227 {
229  set_positions_csv_.reset();
230  return ret;
231 }
quori::message::SetPositions::positions
float positions[3]
Definition: message.hpp:39
quori_controller::SerialDevice::set
void set(const double *const positions, const double *const velocities, const std::size_t length)
Definition: SerialDevice.cpp:164
quori_controller::SerialDevice::getName
const std::string & getName() const
Definition: SerialDevice.cpp:82
quori::message::Type::Log
@ Log
quori::message::SetPositionsRes
Definition: message.hpp:51
quori_controller::SerialDevice::unprocessed_
std::vector< std::uint8_t > unprocessed_
Definition: SerialDevice.hpp:84
operator<<
std::ostream & operator<<(std::ostream &o, const std::vector< T > &data)
Definition: SerialDevice.cpp:19
quori::message::Initialize
Definition: message.hpp:29
quori_controller::SerialDevice::open
static Ptr open(boost::asio::io_service &context, const std::string &path)
Definition: SerialDevice.cpp:38
quori_controller::SerialDevice::attachSetPositionsCsv
void attachSetPositionsCsv(const Csv::Ptr &csv)
Definition: SerialDevice.cpp:220
quori_controller::SerialDevice::~SerialDevice
~SerialDevice()
Definition: SerialDevice.cpp:30
quori_controller::SerialDevice::read
void read()
Definition: SerialDevice.cpp:203
quori::message::Initialized::modes
uint8_t modes[3]
Definition: message.hpp:96
quori::message::Type
Type
Definition: message.hpp:14
quori_controller
Definition: Csv.hpp:10
quori::message::GetStates
Definition: message.hpp:58
quori_controller::SerialDevice::SerialDevice
SerialDevice(boost::asio::posix::stream_descriptor &&fd, const std::string &name)
Definition: SerialDevice.cpp:72
quori_controller::SerialDevice::set_positions_csv_
Csv::Ptr set_positions_csv_
Definition: SerialDevice.hpp:86
quori_controller::SerialDevice::InitializationInfo::joints
std::vector< JointInfo > joints
Definition: SerialDevice.hpp:33
quori::message::SetPositions
Definition: message.hpp:35
quori::message::Set
Definition: message.hpp:42
quori_controller::SerialDevice::name_
std::string name_
Definition: SerialDevice.hpp:77
quori_controller::SerialDevice::InitializationInfo
Definition: SerialDevice.hpp:25
quori_controller::Csv::Ptr
std::shared_ptr< Csv > Ptr
Definition: Csv.hpp:15
quori_controller::SerialDevice::Ptr
std::shared_ptr< SerialDevice > Ptr
Definition: SerialDevice.hpp:36
quori_controller::SerialDevice::initialize
InitializationInfo initialize()
Definition: SerialDevice.cpp:87
quori::message::Set::velocities
float velocities[3]
Definition: message.hpp:47
quori_controller::Joint::Mode
Mode
Definition: Joint.hpp:17
quori_controller::SerialDevice::detachSetPositionsCsv
Csv::Ptr detachSetPositionsCsv()
Definition: SerialDevice.cpp:226
start
ROSCPP_DECL void start()
quori::message::Set::positions
float positions[3]
Definition: message.hpp:46
quori_controller::SerialDevice::stateBuffer_
std::uint8_t * stateBuffer_
Definition: SerialDevice.hpp:82
quori_controller::SerialDevice::InitializationInfo::JointInfo
Definition: SerialDevice.hpp:27
quori_controller::SerialDevice::getState
void getState(quori::message::States &states)
Definition: SerialDevice.cpp:185
std
quori_controller::SerialDevice::fd_
boost::asio::posix::stream_descriptor fd_
Definition: SerialDevice.hpp:76
quori::message::Initialized::_0
char _0[20]
Definition: message.hpp:93
SerialDevice.hpp
quori::message::Initialized
Definition: message.hpp:90
time_since_epoch
double time_since_epoch()
quori::message::States
Definition: message.hpp:109
quori::message::Log
Definition: message.hpp:102
quori_controller::SerialDevice::write
size_t write(const T &msg)
Definition: SerialDevice.hpp:61


quori_controller
Author(s):
autogenerated on Wed Mar 2 2022 00:53:16