mirror of
https://gitlab.com/obbart/universal_robots_ros_driver.git
synced 2026-04-10 01:50:46 +02:00
Implemented ros control
This commit is contained in:
168
include/ur_modern_driver/ros/hardware_interface.h
Normal file
168
include/ur_modern_driver/ros/hardware_interface.h
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <controller_manager/controller_manager.h>
|
||||||
|
#include <hardware_interface/force_torque_sensor_interface.h>
|
||||||
|
#include <hardware_interface/joint_command_interface.h>
|
||||||
|
#include <hardware_interface/joint_state_interface.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "ur_modern_driver/ur/commander.h"
|
||||||
|
#include "ur_modern_driver/ur/rt_state.h"
|
||||||
|
|
||||||
|
class HardwareInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void write() = 0;
|
||||||
|
virtual void start()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void stop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using hardware_interface::JointHandle;
|
||||||
|
using hardware_interface::JointStateHandle;
|
||||||
|
using hardware_interface::JointStateInterface;
|
||||||
|
|
||||||
|
class JointInterface : public JointStateInterface
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::array<double, 6> velocities_, positions_, efforts_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
JointInterface(std::vector<std::string>& joint_names)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
registerHandle(JointStateHandle(joint_names[i], &positions_[i], &velocities_[i], &efforts_[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(RTShared& packet)
|
||||||
|
{
|
||||||
|
positions_ = packet.q_actual;
|
||||||
|
velocities_ = packet.qd_actual;
|
||||||
|
efforts_ = packet.i_actual;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class WrenchInterface : public hardware_interface::ForceTorqueSensorInterface
|
||||||
|
{
|
||||||
|
std::array<double, 6> tcp_;
|
||||||
|
public:
|
||||||
|
WrenchInterface()
|
||||||
|
{
|
||||||
|
registerHandle(hardware_interface::ForceTorqueSensorHandle("wrench", "", tcp_.begin(), tcp_.begin()+3));
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(RTShared& packet)
|
||||||
|
{
|
||||||
|
tcp_ = packet.tcp_force;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class VelocityInterface : public HardwareInterface, public hardware_interface::VelocityJointInterface
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
URCommander& commander_;
|
||||||
|
std::array<double, 6> velocity_cmd_, prev_velocity_cmd_;
|
||||||
|
double max_vel_change_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
VelocityInterface(URCommander& commander, JointStateInterface& js_interface, std::vector<std::string>& joint_names)
|
||||||
|
: commander_(commander)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
registerHandle(JointHandle(js_interface.getHandle(joint_names[i]), &velocity_cmd_[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void write()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
double prev = prev_velocity_cmd_[i];
|
||||||
|
double lo = prev - max_vel_change_;
|
||||||
|
double hi = prev + max_vel_change_;
|
||||||
|
// clamp value to ±max_vel_change
|
||||||
|
prev_velocity_cmd_[i] = std::max(lo, std::min(velocity_cmd_[i], hi));
|
||||||
|
}
|
||||||
|
|
||||||
|
//times 125???
|
||||||
|
commander_.speedj(prev_velocity_cmd_, max_vel_change_ * 125);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::string POSITION_PROGRAM = R"(
|
||||||
|
def driverProg():
|
||||||
|
MULT_jointstate = XXXXX
|
||||||
|
|
||||||
|
SERVO_IDLE = 0
|
||||||
|
SERVO_RUNNING = 1
|
||||||
|
cmd_servo_state = SERVO_IDLE
|
||||||
|
cmd_servo_q = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||||
|
def set_servo_setpoint(q):
|
||||||
|
enter_critical
|
||||||
|
cmd_servo_state = SERVO_RUNNING
|
||||||
|
cmd_servo_q = q
|
||||||
|
exit_critical
|
||||||
|
end
|
||||||
|
thread servoThread():
|
||||||
|
state = SERVO_IDLE
|
||||||
|
while True:
|
||||||
|
enter_critical
|
||||||
|
q = cmd_servo_q
|
||||||
|
do_brake = False
|
||||||
|
if (state == SERVO_RUNNING) and (cmd_servo_state == SERVO_IDLE):
|
||||||
|
do_brake = True
|
||||||
|
end
|
||||||
|
state = cmd_servo_state
|
||||||
|
cmd_servo_state = SERVO_IDLE
|
||||||
|
exit_critical
|
||||||
|
if do_brake:
|
||||||
|
stopj(1.0)
|
||||||
|
sync()
|
||||||
|
elif state == SERVO_RUNNING:
|
||||||
|
servoj(q, YYYYYYYY)
|
||||||
|
else:
|
||||||
|
sync()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
thread_servo = run servoThread()
|
||||||
|
keepalive = 1
|
||||||
|
while keepalive > 0:
|
||||||
|
params_mult = socket_read_binary_integer(6+1)
|
||||||
|
if params_mult[0] > 0:
|
||||||
|
q = [params_mult[1] / MULT_jointstate, params_mult[2] / MULT_jointstate, params_mult[3] / MULT_jointstate, params_mult[4] / MULT_jointstate, params_mult[5] / MULT_jointstate, params_mult[6] / MULT_jointstate]
|
||||||
|
keepalive = params_mult[7]
|
||||||
|
set_servo_setpoint(q)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sleep(.1)
|
||||||
|
socket_close()
|
||||||
|
kill thread_servo
|
||||||
|
end
|
||||||
|
)";
|
||||||
|
|
||||||
|
class PositionInterface : public HardwareInterface, public hardware_interface::PositionJointInterface
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
URCommander& commander_;
|
||||||
|
std::array<double, 6> position_cmd_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PositionInterface(URCommander& commander, JointStateInterface& js_interface, std::vector<std::string>& joint_names)
|
||||||
|
: commander_(commander)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
registerHandle(JointHandle(js_interface.getHandle(joint_names[i]), &position_cmd_[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void write()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
61
include/ur_modern_driver/ros/io_service.h
Normal file
61
include/ur_modern_driver/ros/io_service.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ros/ros.h>
|
||||||
|
#include <ur_msgs/SetIO.h>
|
||||||
|
#include <ur_msgs/SetIORequest.h>
|
||||||
|
#include <ur_msgs/SetIOResponse.h>
|
||||||
|
#include <ur_msgs/SetPayload.h>
|
||||||
|
#include <ur_msgs/SetPayloadRequest.h>
|
||||||
|
#include <ur_msgs/SetPayloadResponse.h>
|
||||||
|
#include "ur_modern_driver/log.h"
|
||||||
|
#include "ur_modern_driver/ur/commander.h"
|
||||||
|
|
||||||
|
class IOService
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ros::NodeHandle nh_;
|
||||||
|
URCommander &commander_;
|
||||||
|
ros::ServiceServer io_service_;
|
||||||
|
ros::ServiceServer payload_service_;
|
||||||
|
|
||||||
|
bool setIO(ur_msgs::SetIORequest& req, ur_msgs::SetIOResponse& resp)
|
||||||
|
{
|
||||||
|
LOG_INFO("setIO called with [%d, %d]", req.fun, req.pin);
|
||||||
|
bool res = false;
|
||||||
|
bool flag = req.state > 0.0 ? true : false;
|
||||||
|
switch(req.fun)
|
||||||
|
{
|
||||||
|
case ur_msgs::SetIO::Request::FUN_SET_DIGITAL_OUT:
|
||||||
|
res = commander_.setDigitalOut(req.pin, flag);
|
||||||
|
break;
|
||||||
|
case ur_msgs::SetIO::Request::FUN_SET_ANALOG_OUT:
|
||||||
|
res = commander_.setAnalogOut(req.pin, req.state);
|
||||||
|
break;
|
||||||
|
case ur_msgs::SetIO::Request::FUN_SET_TOOL_VOLTAGE:
|
||||||
|
res = commander_.setToolVoltage(static_cast<uint8_t>(req.state));
|
||||||
|
break;
|
||||||
|
case ur_msgs::SetIO::Request::FUN_SET_FLAG:
|
||||||
|
res = commander_.setFlag(flag);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.success = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setPayload(ur_msgs::SetPayloadRequest& req, ur_msgs::SetPayloadResponse& resp)
|
||||||
|
{
|
||||||
|
LOG_INFO("setPayload called");
|
||||||
|
//TODO check min and max payload?
|
||||||
|
return resp.success = commander_.setPayload(req.payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
IOService(URCommander &commander)
|
||||||
|
: commander_(commander)
|
||||||
|
, io_service_(nh_.advertiseService("ur_driver/set_io", &IOService::setIO, this))
|
||||||
|
, payload_service_(nh_.advertiseService("ur_driver/set_payload", &IOService::setPayload, this))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
55
include/ur_modern_driver/ros/mb_publisher.h
Normal file
55
include/ur_modern_driver/ros/mb_publisher.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ros/ros.h>
|
||||||
|
#include <ur_msgs/Analog.h>
|
||||||
|
#include <ur_msgs/Digital.h>
|
||||||
|
#include <ur_msgs/IOStates.h>
|
||||||
|
|
||||||
|
#include "ur_modern_driver/ur/consumer.h"
|
||||||
|
|
||||||
|
using namespace ros;
|
||||||
|
|
||||||
|
class MBPublisher : public URStatePacketConsumer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
NodeHandle nh_;
|
||||||
|
Publisher io_pub_;
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
inline void appendDigital(std::vector<ur_msgs::Digital> &vec, std::bitset<N> bits)
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < N; i++)
|
||||||
|
{
|
||||||
|
ur_msgs::Digital digi;
|
||||||
|
digi.pin = static_cast<uint8_t>(i);
|
||||||
|
digi.state = bits.test(i);
|
||||||
|
vec.push_back(digi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void publish(ur_msgs::IOStates &io_msg, SharedMasterBoardData& data);
|
||||||
|
|
||||||
|
public:
|
||||||
|
MBPublisher()
|
||||||
|
: io_pub_(nh_.advertise<ur_msgs::IOStates>("ur_driver/io_states", 1))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool consume(MasterBoardData_V1_X& data);
|
||||||
|
virtual bool consume(MasterBoardData_V3_0__1& data);
|
||||||
|
virtual bool consume(MasterBoardData_V3_2& data);
|
||||||
|
|
||||||
|
virtual bool consume(RobotModeData_V1_X& data);
|
||||||
|
virtual bool consume(RobotModeData_V3_0__1& data);
|
||||||
|
virtual bool consume(RobotModeData_V3_2& data);
|
||||||
|
|
||||||
|
virtual void setupConsumer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void teardownConsumer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void stopConsumer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
46
include/ur_modern_driver/ros/robot_hardware.h
Normal file
46
include/ur_modern_driver/ros/robot_hardware.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <controller_manager/controller_manager.h>
|
||||||
|
#include <hardware_interface/force_torque_sensor_interface.h>
|
||||||
|
#include <hardware_interface/joint_command_interface.h>
|
||||||
|
#include <hardware_interface/joint_state_interface.h>
|
||||||
|
#include <hardware_interface/robot_hw.h>
|
||||||
|
#include "ur_modern_driver/ros/hardware_interface.h"
|
||||||
|
|
||||||
|
using hardware_interface::RobotHW;
|
||||||
|
using hardware_interface::ControllerInfo;
|
||||||
|
|
||||||
|
class RobotHardware : public RobotHW
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
JointInterface joint_interface_;
|
||||||
|
WrenchInterface wrench_interface_;
|
||||||
|
PositionInterface position_interface_;
|
||||||
|
VelocityInterface velocity_interface_;
|
||||||
|
hardware_interface::ForceTorqueSensorInterface force_torque_interface_;
|
||||||
|
HardwareInterface* active_interface_;
|
||||||
|
std::vector<void*> available_interfaces_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RobotHardware(URCommander& commander, std::vector<std::string>& joint_names)
|
||||||
|
: joint_interface_(joint_names)
|
||||||
|
, wrench_interface_()
|
||||||
|
, position_interface_(commander, joint_interface_, joint_names)
|
||||||
|
, velocity_interface_(commander, joint_interface_, joint_names)
|
||||||
|
, available_interfaces_{&position_interface_, &velocity_interface_}
|
||||||
|
{
|
||||||
|
registerInterface<hardware_interface::JointStateInterface>(&joint_interface_);
|
||||||
|
registerInterface<hardware_interface::ForceTorqueSensorInterface>(&wrench_interface_);
|
||||||
|
registerInterface<hardware_interface::PositionJointInterface>(&position_interface_);
|
||||||
|
registerInterface<hardware_interface::VelocityJointInterface>(&velocity_interface_);
|
||||||
|
}
|
||||||
|
|
||||||
|
//bool canSwitch(const std::list<ControllerInfo>& start_list, const std::list<ControllerInfo>& stop_list) const;
|
||||||
|
void doSwitch(const std::list<ControllerInfo>& start_list, const std::list<ControllerInfo>& stop_list);
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Read the state from the robot hardware.
|
||||||
|
virtual void read(RTShared& packet);
|
||||||
|
|
||||||
|
/// \brief write the command to the robot hardware.
|
||||||
|
virtual void write();
|
||||||
|
};
|
||||||
60
include/ur_modern_driver/ros/ros_controller.h
Normal file
60
include/ur_modern_driver/ros/ros_controller.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <ros/ros.h>
|
||||||
|
#include <controller_manager/controller_manager.h>
|
||||||
|
#include "ur_modern_driver/log.h"
|
||||||
|
#include "ur_modern_driver/pipeline.h"
|
||||||
|
#include "ur_modern_driver/ur/rt_state.h"
|
||||||
|
#include "ur_modern_driver/ur/commander.h"
|
||||||
|
#include "ur_modern_driver/ros/robot_hardware.h"
|
||||||
|
|
||||||
|
class ROSController : public URRTPacketConsumer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ros::NodeHandle nh_;
|
||||||
|
ros::Time lastUpdate_;
|
||||||
|
RobotHardware robot_;
|
||||||
|
controller_manager::ControllerManager controller_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ROSController(URCommander& commander, std::vector<std::string>& joint_names)
|
||||||
|
: robot_(commander, joint_names)
|
||||||
|
, controller_(&robot_, nh_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setupConsumer()
|
||||||
|
{
|
||||||
|
lastUpdate_ = ros::Time::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handle(RTShared& state)
|
||||||
|
{
|
||||||
|
auto time = ros::Time::now();
|
||||||
|
auto diff = time - lastUpdate_;
|
||||||
|
lastUpdate_ = time;
|
||||||
|
|
||||||
|
robot_.read(state);
|
||||||
|
controller_.update(time, diff);
|
||||||
|
robot_.write();
|
||||||
|
//todo: return result of write
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool consume(RTState_V1_6__7& state)
|
||||||
|
{
|
||||||
|
return handle(state);
|
||||||
|
}
|
||||||
|
virtual bool consume(RTState_V1_8& state)
|
||||||
|
{
|
||||||
|
return handle(state);
|
||||||
|
}
|
||||||
|
virtual bool consume(RTState_V3_0__1& state)
|
||||||
|
{
|
||||||
|
return handle(state);
|
||||||
|
}
|
||||||
|
virtual bool consume(RTState_V3_2__3& state)
|
||||||
|
{
|
||||||
|
return handle(state);
|
||||||
|
}
|
||||||
|
};
|
||||||
54
src/ros/mb_publisher.cpp
Normal file
54
src/ros/mb_publisher.cpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#include "ur_modern_driver/ros/mb_publisher.h"
|
||||||
|
|
||||||
|
inline void appendAnalog(std::vector<ur_msgs::Analog> &vec, double val, uint8_t pin)
|
||||||
|
{
|
||||||
|
ur_msgs::Analog ana;
|
||||||
|
ana.pin = pin;
|
||||||
|
ana.state = val;
|
||||||
|
vec.push_back(ana);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MBPublisher::publish(ur_msgs::IOStates &io_msg, SharedMasterBoardData& data)
|
||||||
|
{
|
||||||
|
appendAnalog(io_msg.analog_in_states, data.analog_input0, 0);
|
||||||
|
appendAnalog(io_msg.analog_in_states, data.analog_input1, 1);
|
||||||
|
appendAnalog(io_msg.analog_out_states, data.analog_output0, 0);
|
||||||
|
appendAnalog(io_msg.analog_out_states, data.analog_output1, 1);
|
||||||
|
|
||||||
|
io_pub_.publish(io_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MBPublisher::consume(MasterBoardData_V1_X& data)
|
||||||
|
{
|
||||||
|
ur_msgs::IOStates io_msg;
|
||||||
|
appendDigital(io_msg.digital_in_states, data.digital_input_bits);
|
||||||
|
appendDigital(io_msg.digital_out_states, data.digital_output_bits);
|
||||||
|
publish(io_msg, data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool MBPublisher::consume(MasterBoardData_V3_0__1& data)
|
||||||
|
{
|
||||||
|
ur_msgs::IOStates io_msg;
|
||||||
|
appendDigital(io_msg.digital_in_states, data.digital_input_bits);
|
||||||
|
appendDigital(io_msg.digital_out_states, data.digital_output_bits);
|
||||||
|
publish(io_msg, data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool MBPublisher::consume(MasterBoardData_V3_2& data)
|
||||||
|
{
|
||||||
|
consume(static_cast<MasterBoardData_V3_0__1&>(data));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MBPublisher::consume(RobotModeData_V1_X& data)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool MBPublisher::consume(RobotModeData_V3_0__1& data)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool MBPublisher::consume(RobotModeData_V3_2& data)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
76
src/ros/robot_hardware.cpp
Normal file
76
src/ros/robot_hardware.cpp
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#include "ur_modern_driver/ros/robot_hardware.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool RobotHardware::canSwitch(const std::list<ControllerInfo>& start_list,
|
||||||
|
const std::list<ControllerInfo>& stop_list) const
|
||||||
|
{
|
||||||
|
|
||||||
|
bool running = active_interface_ != nullptr;
|
||||||
|
size_t start_size = start_list.size();
|
||||||
|
size_t stop_size = stop_list.size();
|
||||||
|
|
||||||
|
|
||||||
|
for (auto const& ci : stop_list)
|
||||||
|
{
|
||||||
|
auto it = interfaces_.find(ci.hardware_interface);
|
||||||
|
if(it == interfaces_.end() || it->second != active_interface_)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& ci : start_list)
|
||||||
|
{
|
||||||
|
auto it = interfaces_.find(ci.hardware_interface);
|
||||||
|
//we can only start a controller that's already running if we stop it first
|
||||||
|
if(it == interfaces_.end() || (it->second == active_interface_ && stop_size == 0))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void RobotHardware::doSwitch(const std::list<ControllerInfo>& start_list,
|
||||||
|
const std::list<ControllerInfo>& stop_list)
|
||||||
|
{
|
||||||
|
if(active_interface_ != nullptr && stop_list.size() > 0)
|
||||||
|
{
|
||||||
|
active_interface_->stop();
|
||||||
|
active_interface_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto const& ci : start_list)
|
||||||
|
{
|
||||||
|
auto it = interfaces_.find(ci.hardware_interface);
|
||||||
|
if(it == interfaces_.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//we can only switch to one of the available interfaces
|
||||||
|
if(std::find(available_interfaces_.begin(), available_interfaces_.end(), it->second) == available_interfaces_.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto new_interface = static_cast<HardwareInterface*>(it->second);
|
||||||
|
|
||||||
|
if(new_interface == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
LOG_INFO("Starting %s", ci.hardware_interface.c_str());
|
||||||
|
active_interface_ = new_interface;
|
||||||
|
new_interface->start();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RobotHardware::write()
|
||||||
|
{
|
||||||
|
if(active_interface_ == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
active_interface_->write();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RobotHardware::read(RTShared& packet)
|
||||||
|
{
|
||||||
|
joint_interface_.update(packet);
|
||||||
|
wrench_interface_.update(packet);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user