44 CanBus::CanBus(
const std::string& bus_name, CanDataPtr data_ptr,
int thread_priority)
45 : bus_name_(bus_name), data_ptr_(data_ptr)
48 while (!socket_can_.open(bus_name, boost::bind(&CanBus::frameCallback,
this, _1), thread_priority) &&
ros::ok())
51 ROS_INFO(
"Successfully connected to %s.", bus_name.c_str());
53 rm_frame0_.can_id = 0x200;
54 rm_frame0_.can_dlc = 8;
55 rm_frame1_.can_id = 0x1FF;
56 rm_frame1_.can_dlc = 8;
61 bool has_write_frame0 =
false, has_write_frame1 =
false;
63 std::fill(std::begin(rm_frame0_.data), std::end(rm_frame0_.data), 0);
64 std::fill(std::begin(rm_frame1_.data), std::end(rm_frame1_.data), 0);
66 for (
auto& item : *data_ptr_.id2act_data_)
68 if (item.second.type.find(
"rm") != std::string::npos)
70 if (item.second.halted)
72 const ActCoeff& act_coeff = data_ptr_.type2act_coeffs_->find(item.second.type)->second;
73 int id = item.first - 0x201;
75 minAbs(act_coeff.effort2act * item.second.exe_effort, act_coeff.max_out);
76 if (-1 <
id &&
id < 4)
78 rm_frame0_.data[2 * id] =
static_cast<uint8_t
>(
static_cast<int16_t
>(
cmd) >> 8u);
79 rm_frame0_.data[2 *
id + 1] =
static_cast<uint8_t
>(
cmd);
80 has_write_frame0 =
true;
82 else if (3 <
id &&
id < 8)
84 rm_frame1_.data[2 * (
id - 4)] =
static_cast<uint8_t
>(
static_cast<int16_t
>(cmd) >> 8u);
85 rm_frame1_.data[2 * (
id - 4) + 1] =
static_cast<uint8_t
>(cmd);
86 has_write_frame1 =
true;
89 else if (item.second.type.find(
"cheetah") != std::string::npos)
92 const ActCoeff& act_coeff = data_ptr_.type2act_coeffs_->find(item.second.type)->second;
93 frame.can_id = item.first;
95 uint16_t q_des =
static_cast<int>(act_coeff.
pos2act * (item.second.cmd_pos - act_coeff.
act2pos_offset));
96 uint16_t qd_des =
static_cast<int>(act_coeff.
vel2act * (item.second.cmd_vel - act_coeff.
act2vel_offset));
101 frame.data[0] = q_des >> 8;
102 frame.data[1] = q_des & 0xFF;
103 frame.data[2] = qd_des >> 4;
104 frame.data[3] = ((qd_des & 0xF) << 4) | (kp >> 8);
105 frame.data[4] = kp & 0xFF;
106 frame.data[5] = kd >> 4;
107 frame.data[6] = ((kd & 0xF) << 4) | (tau >> 8);
108 frame.data[7] = tau & 0xff;
109 socket_can_.write(&frame);
113 if (has_write_frame0)
114 socket_can_.write(&rm_frame0_);
115 if (has_write_frame1)
116 socket_can_.write(&rm_frame1_);
121 std::lock_guard<std::mutex> guard(mutex_);
123 for (
auto& imu : *data_ptr_.id2imu_data_)
125 imu.second.gyro_updated =
false;
126 imu.second.accel_updated =
false;
129 for (
const auto& frame_stamp : read_buffer_)
131 can_frame frame = frame_stamp.frame;
133 if (data_ptr_.id2act_data_->find(frame.can_id) != data_ptr_.id2act_data_->end())
135 ActData& act_data = data_ptr_.id2act_data_->find(frame.can_id)->second;
136 if ((frame_stamp.stamp - act_data.stamp).toSec() < 0.0005)
138 const ActCoeff& act_coeff = data_ptr_.type2act_coeffs_->find(act_data.type)->second;
139 if (act_data.type.find(
"rm") != std::string::npos)
141 act_data.q_raw = (frame.data[0] << 8u) | frame.data[1];
142 act_data.qd_raw = (frame.data[2] << 8u) | frame.data[3];
143 int16_t cur = (frame.data[4] << 8u) | frame.data[5];
144 act_data.temp = frame.data[6];
147 if (act_data.seq != 0)
149 if (act_data.q_raw - act_data.q_last > 4096)
151 else if (act_data.q_raw - act_data.q_last < -4096)
156 act_data.frequency = 1. / (frame_stamp.stamp - act_data.stamp).toSec();
158 catch (std::runtime_error& ex)
161 act_data.stamp = frame_stamp.stamp;
163 act_data.q_last = act_data.q_raw;
166 act_coeff.act2pos *
static_cast<double>(act_data.q_raw + 8191 * act_data.q_circle) + act_data.offset;
167 act_data.vel = act_coeff.act2vel *
static_cast<double>(act_data.qd_raw);
168 act_data.effort = act_coeff.act2effort *
static_cast<double>(cur);
170 act_data.lp_filter->input(act_data.vel, frame_stamp.stamp);
171 act_data.vel = act_data.lp_filter->output();
176 else if (frame.can_id ==
static_cast<unsigned int>(0x000))
178 if (data_ptr_.id2act_data_->find(frame.data[0]) != data_ptr_.id2act_data_->end())
180 ActData& act_data = data_ptr_.id2act_data_->find(frame.data[0])->second;
181 const ActCoeff& act_coeff = data_ptr_.type2act_coeffs_->find(act_data.type)->second;
182 if (act_data.type.find(
"cheetah") != std::string::npos)
184 act_data.q_raw = (frame.data[1] << 8) | frame.data[2];
185 uint16_t qd = (frame.data[3] << 4) | (frame.data[4] >> 4);
186 uint16_t cur = ((frame.data[4] & 0xF) << 8) | frame.data[5];
189 if (act_data.seq != 0)
191 double pos_new = act_coeff.act2pos *
static_cast<double>(act_data.q_raw) + act_coeff.act2pos_offset +
192 static_cast<double>(act_data.q_circle) * 8 * M_PI + act_data.offset;
193 if (pos_new - act_data.pos > 4 * M_PI)
195 else if (pos_new - act_data.pos < -4 * M_PI)
200 act_data.frequency = 1. / (frame_stamp.stamp - act_data.stamp).toSec();
202 catch (std::runtime_error& ex)
205 act_data.stamp = frame_stamp.stamp;
207 act_data.pos = act_coeff.act2pos *
static_cast<double>(act_data.q_raw) + act_coeff.act2pos_offset +
208 static_cast<double>(act_data.q_circle) * 8 * M_PI + act_data.offset;
210 act_data.vel = act_coeff.act2vel *
static_cast<double>(qd) + act_coeff.act2vel_offset;
211 act_data.effort = act_coeff.act2effort *
static_cast<double>(cur) + act_coeff.act2effort_offset;
213 act_data.lp_filter->input(act_data.vel);
214 act_data.vel = act_data.lp_filter->output();
219 else if (data_ptr_.id2imu_data_->find(frame.can_id) != data_ptr_.id2imu_data_->end())
221 ImuData& imu_data = data_ptr_.id2imu_data_->find(frame.can_id)->second;
222 imu_data.gyro_updated =
true;
223 imu_data.angular_vel[0] = (((int16_t)((frame.data[1]) << 8) | frame.data[0]) * imu_data.angular_vel_coeff) +
224 imu_data.angular_vel_offset[0];
225 imu_data.angular_vel[1] = (((int16_t)((frame.data[3]) << 8) | frame.data[2]) * imu_data.angular_vel_coeff) +
226 imu_data.angular_vel_offset[1];
227 imu_data.angular_vel[2] = (((int16_t)((frame.data[5]) << 8) | frame.data[4]) * imu_data.angular_vel_coeff) +
228 imu_data.angular_vel_offset[2];
229 imu_data.time_stamp = frame_stamp.stamp;
230 int16_t temp = (int16_t)((frame.data[6] << 3) | (frame.data[7] >> 5));
233 imu_data.temperature = temp * imu_data.temp_coeff + imu_data.temp_offset;
236 else if (data_ptr_.id2imu_data_->find(frame.can_id - 1) != data_ptr_.id2imu_data_->end())
238 ImuData& imu_data = data_ptr_.id2imu_data_->find(frame.can_id - 1)->second;
239 imu_data.accel_updated =
true;
240 imu_data.linear_acc[0] = ((int16_t)((frame.data[1]) << 8) | frame.data[0]) * imu_data.accel_coeff;
241 imu_data.linear_acc[1] = ((int16_t)((frame.data[3]) << 8) | frame.data[2]) * imu_data.accel_coeff;
242 imu_data.linear_acc[2] = ((int16_t)((frame.data[5]) << 8) | frame.data[4]) * imu_data.accel_coeff;
243 imu_data.time_stamp = frame_stamp.stamp;
244 imu_data.camera_trigger = frame.data[6] & 1;
245 imu_data.enabled_trigger = frame.data[6] & 2;
246 imu_data.imu_filter->update(frame_stamp.stamp, imu_data.linear_acc, imu_data.angular_vel, imu_data.ori,
247 imu_data.linear_acc_cov, imu_data.angular_vel_cov, imu_data.ori_cov,
248 imu_data.temperature, imu_data.camera_trigger && imu_data.enabled_trigger);
251 else if (data_ptr_.id2tof_data_->find(frame.can_id) != data_ptr_.id2tof_data_->end())
253 TofData& tof_data = data_ptr_.id2tof_data_->find(frame.can_id)->second;
254 tof_data.distance = ((int16_t)((frame.data[1]) << 8) | frame.data[0]);
255 tof_data.strength = ((int16_t)((frame.data[3]) << 8) | frame.data[2]);
258 if (frame.can_id != 0x0)
260 <<
" on bus: " << bus_name_);
262 read_buffer_.clear();
265 void CanBus::write(can_frame* frame)
267 socket_can_.write(frame);
270 void CanBus::frameCallback(
const can_frame& frame)
272 std::lock_guard<std::mutex> guard(mutex_);
273 CanFrameStamp can_frame_stamp{ .frame = frame, .stamp =
ros::Time::now() };
274 read_buffer_.push_back(can_frame_stamp);