openarm_ros2/openarm_hardware/src/canbus.cpp
thomason 595fbe7745
Implement openarm ros2_control support with openarm_hardware and openarm_bringup (#2)
- openarm_bringup: ros2_control bringup
- openarm_hardware: hardware interface for ros2_control
2025-03-28 18:05:38 +09:00

69 lines
1.8 KiB
C++

#include "canbus.hpp"
#include <poll.h>
CANBus::CANBus(const std::string& interface) {
struct ifreq ifr;
struct sockaddr_can addr;
sock_ = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (sock_ < 0) {
perror("Error while opening CAN socket");
exit(EXIT_FAILURE);
}
std::strncpy(ifr.ifr_name, interface.c_str(), IFNAMSIZ);
if (ioctl(sock_, SIOCGIFINDEX, &ifr) < 0) {
perror("Error getting interface index");
exit(EXIT_FAILURE);
}
std::memset(&addr, 0, sizeof(addr));
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(sock_, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
perror("Error in CAN socket bind");
exit(EXIT_FAILURE);
}
}
CANBus::~CANBus() {
close(sock_);
}
bool CANBus::send(uint16_t motor_id, const std::array<uint8_t, 8>& data) {
struct can_frame frame;
std::memset(&frame, 0, sizeof(frame));
frame.can_id = motor_id;
frame.can_dlc = data.size();
std::copy(data.begin(), data.end(), frame.data);
if (write(sock_, &frame, sizeof(frame)) != sizeof(frame)) {
perror("Error sending CAN frame");
return false;
} else {
// std::cout << "Sent CAN frame to motor ID " << motor_id << std::endl;
return true;
}
}
struct can_frame CANBus::recv() {
struct can_frame frame;
std::memset(&frame, 0, sizeof(frame));
// change socket into non blocking mode
// int flags = fcntl(sock_, F_GETFL, 0);
// fcntl(sock_, F_SETFL, flags | O_NONBLOCK);
int nbytes = read(sock_, &frame, sizeof(struct can_frame));
if (nbytes < 0) {
perror("CAN read error");
} else {
// std::cout << "Received CAN frame from motor ID " << frame.can_id << std::endl;
}
return frame;
}