Compare commits

10 Commits

55 changed files with 1352 additions and 2516 deletions

View File

@@ -1,68 +1,30 @@
cmake_minimum_required(VERSION 3.0.2) cmake_minimum_required(VERSION 3.8)
project(sas_robot_driver_franka) project(sas_robot_driver_franka)
## Compile as C++11, supported in ROS Kinetic and newer ## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11) # add_compile_options(-std=c++11)
#add_compile_options(-std=c++11) #add_compile_options(-std=c++11)
add_compile_options(-Werror=return-type) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
#Add custom (non compiling) targets so launch scripts and python files show up in QT Creator's project view. find_package(pybind11 REQUIRED)
file(GLOB_RECURSE EXTRA_FILES */*) find_package(ament_cmake REQUIRED)
#add_custom_target(${PROJECT_NAME}_OTHER_FILES ALL WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} SOURCES ${EXTRA_FILES}) find_package(rclcpp REQUIRED)
add_custom_target(cfg ALL WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} SOURCES ${EXTRA_FILES}) find_package(geometry_msgs REQUIRED)
find_package(std_msgs REQUIRED)
## Find catkin macros and libraries find_package(sas_common REQUIRED)
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) find_package(sas_core REQUIRED)
## is used, also find other catkin packages find_package(sas_conversions REQUIRED)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
tf2_ros
tf2
sas_common
sas_clock
sas_robot_driver
sas_patient_side_manager
message_generation
pybind11_catkin
)
add_service_files(
DIRECTORY srv
FILES
Move.srv
Grasp.srv
)
add_message_files(
DIRECTORY msg
FILES
GripperState.msg
)
catkin_python_setup()
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
INCLUDE_DIRS include
CATKIN_DEPENDS roscpp rospy sas_common sas_clock sas_robot_driver tf2_ros tf2 pybind11_catkin message_runtime std_msgs
)
find_package(Franka REQUIRED)
find_package(Eigen3 REQUIRED) find_package(Eigen3 REQUIRED)
find_package(yaml-cpp REQUIRED) find_package(tf2_ros REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR}) find_package(tf2 REQUIRED)
find_package(sas_robot_driver REQUIRED)
find_package(Franka REQUIRED)
find_package(sas_robot_driver_franka_interfaces REQUIRED) # Add this line
# To correctly find and link with QT ## To correctly find and link with QT
set(CMAKE_PREFIX_PATH $ENV{QT_PATH}) set(CMAKE_PREFIX_PATH $ENV{QT_PATH})
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
@@ -72,15 +34,76 @@ if (CMAKE_VERSION VERSION_LESS "3.7.0")
endif () endif ()
find_package(Qt5 COMPONENTS Widgets REQUIRED) find_package(Qt5 COMPONENTS Widgets REQUIRED)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) ##### CPP LIBRARY initial #####
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) include_directories(
include
constraints_manager/include
)
install(
DIRECTORY include/
DESTINATION include
)
ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET)
ament_export_dependencies(Eigen3 rclcpp geometry_msgs std_msgs
sas_common sas_core sas_conversions sas_robot_driver_franka_interfaces
tf2_ros tf2 sas_robot_driver)
##### CPP LIBRARY initial end #####
##### CPP LIBRARY ROBOT_DYNAMICS #####
add_library(${PROJECT_NAME}_robot_dynamics SHARED
src/robot_dynamics/qros_robot_dynamics_client.cpp
src/robot_dynamics/qros_robot_dynamics_server.cpp
)
ament_target_dependencies(${PROJECT_NAME}_robot_dynamics
rclcpp geometry_msgs std_msgs
sas_common sas_core sas_conversions
tf2_ros tf2 sas_robot_driver)
target_include_directories(${PROJECT_NAME}_robot_dynamics
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_link_libraries(${PROJECT_NAME}_robot_dynamics
-ldqrobotics
Eigen3::Eigen
)
install(
TARGETS ${PROJECT_NAME}_robot_dynamics # ${PROJECT_NAME}
EXPORT export_${PROJECT_NAME} #export_${PROJECT_NAME}
LIBRARY DESTINATION lib
#ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)
##END## CPP LIBRARY ROBOT_DYNAMICS #####
##### CPP LIBRARY Motion Generation #####
add_library(MotionGenerator src/generator/motion_generator.cpp) add_library(MotionGenerator src/generator/motion_generator.cpp)
target_link_libraries(MotionGenerator Franka::Franka) target_link_libraries(MotionGenerator Franka::Franka Eigen3::Eigen)
add_library(ConstraintsManager constraints_manager/src/constraints_manager.cpp) add_library(ConstraintsManager constraints_manager/src/constraints_manager.cpp)
target_link_libraries(ConstraintsManager Eigen3::Eigen)
install(
DIRECTORY constraints_manager/include/
DESTINATION include/constraints_manager
)
target_include_directories(ConstraintsManager
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/constraints_manager/include>
$<INSTALL_INTERFACE:include/constraints_manager>)
add_library(QuadraticProgramMotionGenerator src/generator/quadratic_program_motion_generator.cpp) add_library(QuadraticProgramMotionGenerator src/generator/quadratic_program_motion_generator.cpp)
target_link_libraries(QuadraticProgramMotionGenerator target_link_libraries(QuadraticProgramMotionGenerator
@@ -88,12 +111,18 @@ target_link_libraries(QuadraticProgramMotionGenerator
dqrobotics dqrobotics
ConstraintsManager) ConstraintsManager)
add_library(CustomMotionGeneration src/generator/custom_motion_generation.cpp) add_library(CustomMotionGeneration src/generator/custom_motion_generation.cpp)
target_link_libraries(CustomMotionGeneration target_link_libraries(CustomMotionGeneration
qpOASES qpOASES
dqrobotics dqrobotics
ConstraintsManager) ConstraintsManager)
##### CPP LIBRARY Motion Generation end #####
##### CPP LIBRARY franka low level interface #####
add_library(robot_interface_franka src/joint/robot_interface_franka.cpp) add_library(robot_interface_franka src/joint/robot_interface_franka.cpp)
target_link_libraries(robot_interface_franka Franka::Franka target_link_libraries(robot_interface_franka Franka::Franka
dqrobotics dqrobotics
@@ -107,133 +136,157 @@ target_link_libraries(robot_interface_hand Franka::Franka
dqrobotics) dqrobotics)
############ ##### CPP LIBRARY franka low level interface end #####
## Build ###
############
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
include
include/generator
src/
src/robot_dynamics
src/hand
src/joint
${catkin_INCLUDE_DIRS}
constraints_manager/include
)
add_library(qros_robot_dynamics_provider src/robot_dynamics/qros_robot_dynamics_provider.cpp)
target_link_libraries(qros_robot_dynamics_provider
${catkin_LIBRARIES}
dqrobotics)
add_library(qros_robot_dynamics_interface src/robot_dynamics/qros_robot_dynamics_interface.cpp)
target_link_libraries(qros_robot_dynamics_interface
${catkin_LIBRARIES}
dqrobotics)
##### SAS Franka Robot Driver #####
add_library(sas_robot_driver_franka src/joint/sas_robot_driver_franka.cpp) add_library(sas_robot_driver_franka src/joint/sas_robot_driver_franka.cpp)
target_link_libraries(sas_robot_driver_franka target_link_libraries(sas_robot_driver_franka
qros_robot_dynamics_provider ${PROJECT_NAME}_robot_dynamics
dqrobotics dqrobotics
dqrobotics-interface-json11 dqrobotics-interface-json11
robot_interface_franka) robot_interface_franka)
##### SAS Franka Robot Driver end #####
##### qros hand effector driver #####
add_library(qros_effector_driver_franka_hand src/hand/qros_effector_driver_franka_hand.cpp) add_library(qros_effector_driver_franka_hand src/hand/qros_effector_driver_franka_hand.cpp)
ament_target_dependencies(qros_effector_driver_franka_hand
rclcpp sas_common sas_core
sas_robot_driver_franka_interfaces
)
#ament_target_dependencies(${PROJECT_NAME}_robot_dynamics
# rclcpp geometry_msgs std_msgs
# sas_common sas_core sas_conversions
# tf2_ros tf2 sas_robot_driver)
target_link_libraries(qros_effector_driver_franka_hand target_link_libraries(qros_effector_driver_franka_hand
dqrobotics dqrobotics
# robot_interface_hand
Franka::Franka) Franka::Franka)
#target_include_directories(qros_effector_driver_franka_hand
# PUBLIC
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/interface>
# $<INSTALL_INTERFACE:include/interface>)
add_library(sas_robot_driver_coppelia src/coppelia/sas_robot_driver_coppelia.cpp) ##### qros hand effector driver end #####
target_link_libraries(sas_robot_driver_coppelia
dqrobotics
dqrobotics-interface-vrep)
add_dependencies(sas_robot_driver_franka ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(sas_robot_driver_coppelia ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(qros_effector_driver_franka_hand ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_executable(sas_robot_driver_coppelia_node src/sas_robot_driver_coppelia_node.cpp) ##### SAS Franka Robot Driver Node #####
target_link_libraries(sas_robot_driver_coppelia_node
sas_robot_driver_coppelia
${catkin_LIBRARIES})
add_executable(sas_robot_driver_franka_node src/sas_robot_driver_franka_node.cpp) add_executable(sas_robot_driver_franka_node src/sas_robot_driver_franka_node.cpp)
target_link_libraries(sas_robot_driver_franka_node ament_target_dependencies(sas_robot_driver_franka_node
sas_robot_driver_franka rclcpp sas_common sas_core
${catkin_LIBRARIES}) sas_robot_driver)
target_link_libraries(sas_robot_driver_franka_node sas_robot_driver_franka)
install(TARGETS
sas_robot_driver_franka_node
DESTINATION lib/${PROJECT_NAME})
##### SAS Franka Robot Hand Driver Node #####
add_executable(sas_robot_driver_franka_hand_node src/sas_robot_driver_franka_hand_node.cpp) add_executable(sas_robot_driver_franka_hand_node src/sas_robot_driver_franka_hand_node.cpp)
ament_target_dependencies(sas_robot_driver_franka_node
rclcpp sas_common sas_core)
target_link_libraries(sas_robot_driver_franka_hand_node target_link_libraries(sas_robot_driver_franka_hand_node
qros_effector_driver_franka_hand qros_effector_driver_franka_hand)
${catkin_LIBRARIES})
install(TARGETS
sas_robot_driver_franka_hand_node
DESTINATION lib/${PROJECT_NAME})
##### Coppelia Mirror Node #####
add_executable(sas_robot_driver_franka_coppelia_node
src/sas_robot_driver_coppelia_node.cpp
src/coppelia/sas_robot_driver_coppelia.cpp
)
ament_target_dependencies(sas_robot_driver_franka_coppelia_node
rclcpp sas_common sas_core sas_conversions sas_robot_driver
)
target_link_libraries(sas_robot_driver_franka_coppelia_node
dqrobotics
dqrobotics-interface-json11
dqrobotics-interface-vrep
)
install(TARGETS
sas_robot_driver_franka_coppelia_node
DESTINATION lib/${PROJECT_NAME})
##### JuanEmika
add_executable(JuankaEmika add_executable(JuankaEmika
qt/configuration_window/main.cpp qt/configuration_window/main.cpp
qt/configuration_window/mainwindow.cpp qt/configuration_window/mainwindow.cpp
qt/configuration_window/mainwindow.ui qt/configuration_window/mainwindow.ui
) )
ament_target_dependencies(sas_robot_driver_franka_node
rclcpp sas_common sas_core
sas_robot_driver)
target_link_libraries(JuankaEmika PRIVATE Qt${QT_VERSION_MAJOR}::Widgets target_link_libraries(JuankaEmika PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
dqrobotics dqrobotics
${catkin_LIBRARIES}
robot_interface_franka robot_interface_franka
) )
#####################################################################################
# python binding
include_directories(
include/robot_dynamic
)
pybind_add_module(_qros_robot_dynamic SHARED
src/robot_dynamics/qros_robot_dynamic_py.cpp src/robot_dynamics/qros_robot_dynamics_interface.cpp src/robot_dynamics/qros_robot_dynamics_provider.cpp
)
target_compile_definitions(_qros_robot_dynamic PRIVATE BUILD_PYBIND)
# https://github.com/pybind/pybind11/issues/387
target_link_libraries(_qros_robot_dynamic PRIVATE ${catkin_LIBRARIES} -ldqrobotics)
if (QT_VERSION_MAJOR EQUAL 6) if (QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(JuankaEmika) qt_finalize_executable(JuankaEmika)
endif () endif ()
install(TARGETS ${PROJECT_NAME} install(TARGETS
DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} JuankaEmika
DESTINATION lib/${PROJECT_NAME})
##### PYBIND11 LIBRARY ROBOT_DYNAMICS #####
ament_python_install_package(${PROJECT_NAME})
pybind11_add_module(_qros_franka_robot_dynamic SHARED
src/robot_dynamics/qros_robot_dynamics_py.cpp
src/robot_dynamics/qros_robot_dynamics_client.cpp
src/robot_dynamics/qros_robot_dynamics_server.cpp
) )
install(TARGETS sas_robot_driver_franka_node target_include_directories(_qros_franka_robot_dynamic
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} PUBLIC
) $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/robot_dynamics>
$<INSTALL_INTERFACE:include/robot_dynamics>)
install(TARGETS sas_robot_driver_coppelia_node target_compile_definitions(_qros_franka_robot_dynamic PRIVATE IS_SAS_PYTHON_BUILD)
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} # https://github.com/pybind/pybind11/issues/387
) target_link_libraries(_qros_franka_robot_dynamic PRIVATE ${PROJECT_NAME}_robot_dynamics -ldqrobotics)
install(TARGETS sas_robot_driver_franka_hand_node install(TARGETS _qros_franka_robot_dynamic
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} DESTINATION "${PYTHON_INSTALL_DIR}/${PROJECT_NAME}"
) )
##END## PYBIND11 LIBRARY ROBOT_DYNAMICS #####
## Mark cpp header files for installation
install(DIRECTORY include/${PROJECT_NAME}/ install(
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} DIRECTORY include/
FILES_MATCHING PATTERN "*.h" DESTINATION include
# PATTERN ".svn" EXCLUDE
) )
install(TARGETS _qros_robot_dynamic
LIBRARY DESTINATION ${PYTHON_INSTALL_DIR}
##### LAUNCH FILES #####
install(DIRECTORY
launch
DESTINATION share/${PROJECT_NAME}/
) )
##END## LAUNCH FILES #####
ament_package()

View File

@@ -1,123 +0,0 @@
// Generated by gencpp from file sas_robot_driver_franka/Grasp.msg
// DO NOT EDIT!
#ifndef SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRASP_H
#define SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRASP_H
#include <ros/service_traits.h>
#include <sas_robot_driver_franka/GraspRequest.h>
#include <sas_robot_driver_franka/GraspResponse.h>
namespace sas_robot_driver_franka
{
struct Grasp
{
typedef GraspRequest Request;
typedef GraspResponse Response;
Request request;
Response response;
typedef Request RequestType;
typedef Response ResponseType;
}; // struct Grasp
} // namespace sas_robot_driver_franka
namespace ros
{
namespace service_traits
{
template<>
struct MD5Sum< ::sas_robot_driver_franka::Grasp > {
static const char* value()
{
return "6752ec080e002a60682f31654d420583";
}
static const char* value(const ::sas_robot_driver_franka::Grasp&) { return value(); }
};
template<>
struct DataType< ::sas_robot_driver_franka::Grasp > {
static const char* value()
{
return "sas_robot_driver_franka/Grasp";
}
static const char* value(const ::sas_robot_driver_franka::Grasp&) { return value(); }
};
// service_traits::MD5Sum< ::sas_robot_driver_franka::GraspRequest> should match
// service_traits::MD5Sum< ::sas_robot_driver_franka::Grasp >
template<>
struct MD5Sum< ::sas_robot_driver_franka::GraspRequest>
{
static const char* value()
{
return MD5Sum< ::sas_robot_driver_franka::Grasp >::value();
}
static const char* value(const ::sas_robot_driver_franka::GraspRequest&)
{
return value();
}
};
// service_traits::DataType< ::sas_robot_driver_franka::GraspRequest> should match
// service_traits::DataType< ::sas_robot_driver_franka::Grasp >
template<>
struct DataType< ::sas_robot_driver_franka::GraspRequest>
{
static const char* value()
{
return DataType< ::sas_robot_driver_franka::Grasp >::value();
}
static const char* value(const ::sas_robot_driver_franka::GraspRequest&)
{
return value();
}
};
// service_traits::MD5Sum< ::sas_robot_driver_franka::GraspResponse> should match
// service_traits::MD5Sum< ::sas_robot_driver_franka::Grasp >
template<>
struct MD5Sum< ::sas_robot_driver_franka::GraspResponse>
{
static const char* value()
{
return MD5Sum< ::sas_robot_driver_franka::Grasp >::value();
}
static const char* value(const ::sas_robot_driver_franka::GraspResponse&)
{
return value();
}
};
// service_traits::DataType< ::sas_robot_driver_franka::GraspResponse> should match
// service_traits::DataType< ::sas_robot_driver_franka::Grasp >
template<>
struct DataType< ::sas_robot_driver_franka::GraspResponse>
{
static const char* value()
{
return DataType< ::sas_robot_driver_franka::Grasp >::value();
}
static const char* value(const ::sas_robot_driver_franka::GraspResponse&)
{
return value();
}
};
} // namespace service_traits
} // namespace ros
#endif // SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRASP_H

View File

@@ -1,235 +0,0 @@
// Generated by gencpp from file sas_robot_driver_franka/GraspRequest.msg
// DO NOT EDIT!
#ifndef SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRASPREQUEST_H
#define SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRASPREQUEST_H
#include <string>
#include <vector>
#include <memory>
#include <ros/types.h>
#include <ros/serialization.h>
#include <ros/builtin_message_traits.h>
#include <ros/message_operations.h>
namespace sas_robot_driver_franka
{
template <class ContainerAllocator>
struct GraspRequest_
{
typedef GraspRequest_<ContainerAllocator> Type;
GraspRequest_()
: width(0.0)
, speed(0.0)
, force(0.0)
, epsilon_inner(0.0)
, epsilon_outer(0.0) {
}
GraspRequest_(const ContainerAllocator& _alloc)
: width(0.0)
, speed(0.0)
, force(0.0)
, epsilon_inner(0.0)
, epsilon_outer(0.0) {
(void)_alloc;
}
typedef float _width_type;
_width_type width;
typedef float _speed_type;
_speed_type speed;
typedef float _force_type;
_force_type force;
typedef float _epsilon_inner_type;
_epsilon_inner_type epsilon_inner;
typedef float _epsilon_outer_type;
_epsilon_outer_type epsilon_outer;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> > Ptr;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> const> ConstPtr;
}; // struct GraspRequest_
typedef ::sas_robot_driver_franka::GraspRequest_<std::allocator<void> > GraspRequest;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GraspRequest > GraspRequestPtr;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GraspRequest const> GraspRequestConstPtr;
// constants requiring out of line definition
template<typename ContainerAllocator>
std::ostream& operator<<(std::ostream& s, const ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> & v)
{
ros::message_operations::Printer< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> >::stream(s, "", v);
return s;
}
template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator==(const ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator1> & lhs, const ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator2> & rhs)
{
return lhs.width == rhs.width &&
lhs.speed == rhs.speed &&
lhs.force == rhs.force &&
lhs.epsilon_inner == rhs.epsilon_inner &&
lhs.epsilon_outer == rhs.epsilon_outer;
}
template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator!=(const ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator1> & lhs, const ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator2> & rhs)
{
return !(lhs == rhs);
}
} // namespace sas_robot_driver_franka
namespace ros
{
namespace message_traits
{
template <class ContainerAllocator>
struct IsMessage< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> >
: TrueType
{ };
template <class ContainerAllocator>
struct IsMessage< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> const>
: TrueType
{ };
template <class ContainerAllocator>
struct IsFixedSize< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> >
: TrueType
{ };
template <class ContainerAllocator>
struct IsFixedSize< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> const>
: TrueType
{ };
template <class ContainerAllocator>
struct HasHeader< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> >
: FalseType
{ };
template <class ContainerAllocator>
struct HasHeader< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> const>
: FalseType
{ };
template<class ContainerAllocator>
struct MD5Sum< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> >
{
static const char* value()
{
return "337f46ba15e58c568d47e27881cf893c";
}
static const char* value(const ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator>&) { return value(); }
static const uint64_t static_value1 = 0x337f46ba15e58c56ULL;
static const uint64_t static_value2 = 0x8d47e27881cf893cULL;
};
template<class ContainerAllocator>
struct DataType< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> >
{
static const char* value()
{
return "sas_robot_driver_franka/GraspRequest";
}
static const char* value(const ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator>&) { return value(); }
};
template<class ContainerAllocator>
struct Definition< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> >
{
static const char* value()
{
return "float32 width\n"
"float32 speed\n"
"float32 force\n"
"float32 epsilon_inner\n"
"float32 epsilon_outer\n"
;
}
static const char* value(const ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator>&) { return value(); }
};
} // namespace message_traits
} // namespace ros
namespace ros
{
namespace serialization
{
template<class ContainerAllocator> struct Serializer< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> >
{
template<typename Stream, typename T> inline static void allInOne(Stream& stream, T m)
{
stream.next(m.width);
stream.next(m.speed);
stream.next(m.force);
stream.next(m.epsilon_inner);
stream.next(m.epsilon_outer);
}
ROS_DECLARE_ALLINONE_SERIALIZER
}; // struct GraspRequest_
} // namespace serialization
} // namespace ros
namespace ros
{
namespace message_operations
{
template<class ContainerAllocator>
struct Printer< ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator> >
{
template<typename Stream> static void stream(Stream& s, const std::string& indent, const ::sas_robot_driver_franka::GraspRequest_<ContainerAllocator>& v)
{
s << indent << "width: ";
Printer<float>::stream(s, indent + " ", v.width);
s << indent << "speed: ";
Printer<float>::stream(s, indent + " ", v.speed);
s << indent << "force: ";
Printer<float>::stream(s, indent + " ", v.force);
s << indent << "epsilon_inner: ";
Printer<float>::stream(s, indent + " ", v.epsilon_inner);
s << indent << "epsilon_outer: ";
Printer<float>::stream(s, indent + " ", v.epsilon_outer);
}
};
} // namespace message_operations
} // namespace ros
#endif // SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRASPREQUEST_H

View File

@@ -1,195 +0,0 @@
// Generated by gencpp from file sas_robot_driver_franka/GraspResponse.msg
// DO NOT EDIT!
#ifndef SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRASPRESPONSE_H
#define SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRASPRESPONSE_H
#include <string>
#include <vector>
#include <memory>
#include <ros/types.h>
#include <ros/serialization.h>
#include <ros/builtin_message_traits.h>
#include <ros/message_operations.h>
namespace sas_robot_driver_franka
{
template <class ContainerAllocator>
struct GraspResponse_
{
typedef GraspResponse_<ContainerAllocator> Type;
GraspResponse_()
: success(false) {
}
GraspResponse_(const ContainerAllocator& _alloc)
: success(false) {
(void)_alloc;
}
typedef uint8_t _success_type;
_success_type success;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> > Ptr;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> const> ConstPtr;
}; // struct GraspResponse_
typedef ::sas_robot_driver_franka::GraspResponse_<std::allocator<void> > GraspResponse;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GraspResponse > GraspResponsePtr;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GraspResponse const> GraspResponseConstPtr;
// constants requiring out of line definition
template<typename ContainerAllocator>
std::ostream& operator<<(std::ostream& s, const ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> & v)
{
ros::message_operations::Printer< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> >::stream(s, "", v);
return s;
}
template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator==(const ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator1> & lhs, const ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator2> & rhs)
{
return lhs.success == rhs.success;
}
template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator!=(const ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator1> & lhs, const ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator2> & rhs)
{
return !(lhs == rhs);
}
} // namespace sas_robot_driver_franka
namespace ros
{
namespace message_traits
{
template <class ContainerAllocator>
struct IsMessage< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> >
: TrueType
{ };
template <class ContainerAllocator>
struct IsMessage< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> const>
: TrueType
{ };
template <class ContainerAllocator>
struct IsFixedSize< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> >
: TrueType
{ };
template <class ContainerAllocator>
struct IsFixedSize< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> const>
: TrueType
{ };
template <class ContainerAllocator>
struct HasHeader< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> >
: FalseType
{ };
template <class ContainerAllocator>
struct HasHeader< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> const>
: FalseType
{ };
template<class ContainerAllocator>
struct MD5Sum< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> >
{
static const char* value()
{
return "358e233cde0c8a8bcfea4ce193f8fc15";
}
static const char* value(const ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator>&) { return value(); }
static const uint64_t static_value1 = 0x358e233cde0c8a8bULL;
static const uint64_t static_value2 = 0xcfea4ce193f8fc15ULL;
};
template<class ContainerAllocator>
struct DataType< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> >
{
static const char* value()
{
return "sas_robot_driver_franka/GraspResponse";
}
static const char* value(const ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator>&) { return value(); }
};
template<class ContainerAllocator>
struct Definition< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> >
{
static const char* value()
{
return "bool success\n"
;
}
static const char* value(const ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator>&) { return value(); }
};
} // namespace message_traits
} // namespace ros
namespace ros
{
namespace serialization
{
template<class ContainerAllocator> struct Serializer< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> >
{
template<typename Stream, typename T> inline static void allInOne(Stream& stream, T m)
{
stream.next(m.success);
}
ROS_DECLARE_ALLINONE_SERIALIZER
}; // struct GraspResponse_
} // namespace serialization
} // namespace ros
namespace ros
{
namespace message_operations
{
template<class ContainerAllocator>
struct Printer< ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator> >
{
template<typename Stream> static void stream(Stream& s, const std::string& indent, const ::sas_robot_driver_franka::GraspResponse_<ContainerAllocator>& v)
{
s << indent << "success: ";
Printer<uint8_t>::stream(s, indent + " ", v.success);
}
};
} // namespace message_operations
} // namespace ros
#endif // SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRASPRESPONSE_H

View File

@@ -1,235 +0,0 @@
// Generated by gencpp from file sas_robot_driver_franka/GripperState.msg
// DO NOT EDIT!
#ifndef SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRIPPERSTATE_H
#define SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRIPPERSTATE_H
#include <string>
#include <vector>
#include <memory>
#include <ros/types.h>
#include <ros/serialization.h>
#include <ros/builtin_message_traits.h>
#include <ros/message_operations.h>
namespace sas_robot_driver_franka
{
template <class ContainerAllocator>
struct GripperState_
{
typedef GripperState_<ContainerAllocator> Type;
GripperState_()
: width(0.0)
, max_width(0.0)
, is_grasped(false)
, temperature(0)
, duration_ms(0) {
}
GripperState_(const ContainerAllocator& _alloc)
: width(0.0)
, max_width(0.0)
, is_grasped(false)
, temperature(0)
, duration_ms(0) {
(void)_alloc;
}
typedef float _width_type;
_width_type width;
typedef float _max_width_type;
_max_width_type max_width;
typedef uint8_t _is_grasped_type;
_is_grasped_type is_grasped;
typedef uint16_t _temperature_type;
_temperature_type temperature;
typedef uint64_t _duration_ms_type;
_duration_ms_type duration_ms;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> > Ptr;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> const> ConstPtr;
}; // struct GripperState_
typedef ::sas_robot_driver_franka::GripperState_<std::allocator<void> > GripperState;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GripperState > GripperStatePtr;
typedef boost::shared_ptr< ::sas_robot_driver_franka::GripperState const> GripperStateConstPtr;
// constants requiring out of line definition
template<typename ContainerAllocator>
std::ostream& operator<<(std::ostream& s, const ::sas_robot_driver_franka::GripperState_<ContainerAllocator> & v)
{
ros::message_operations::Printer< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> >::stream(s, "", v);
return s;
}
template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator==(const ::sas_robot_driver_franka::GripperState_<ContainerAllocator1> & lhs, const ::sas_robot_driver_franka::GripperState_<ContainerAllocator2> & rhs)
{
return lhs.width == rhs.width &&
lhs.max_width == rhs.max_width &&
lhs.is_grasped == rhs.is_grasped &&
lhs.temperature == rhs.temperature &&
lhs.duration_ms == rhs.duration_ms;
}
template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator!=(const ::sas_robot_driver_franka::GripperState_<ContainerAllocator1> & lhs, const ::sas_robot_driver_franka::GripperState_<ContainerAllocator2> & rhs)
{
return !(lhs == rhs);
}
} // namespace sas_robot_driver_franka
namespace ros
{
namespace message_traits
{
template <class ContainerAllocator>
struct IsMessage< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> >
: TrueType
{ };
template <class ContainerAllocator>
struct IsMessage< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> const>
: TrueType
{ };
template <class ContainerAllocator>
struct IsFixedSize< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> >
: TrueType
{ };
template <class ContainerAllocator>
struct IsFixedSize< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> const>
: TrueType
{ };
template <class ContainerAllocator>
struct HasHeader< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> >
: FalseType
{ };
template <class ContainerAllocator>
struct HasHeader< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> const>
: FalseType
{ };
template<class ContainerAllocator>
struct MD5Sum< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> >
{
static const char* value()
{
return "53f8669159aaded70b1783087f07679d";
}
static const char* value(const ::sas_robot_driver_franka::GripperState_<ContainerAllocator>&) { return value(); }
static const uint64_t static_value1 = 0x53f8669159aaded7ULL;
static const uint64_t static_value2 = 0x0b1783087f07679dULL;
};
template<class ContainerAllocator>
struct DataType< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> >
{
static const char* value()
{
return "sas_robot_driver_franka/GripperState";
}
static const char* value(const ::sas_robot_driver_franka::GripperState_<ContainerAllocator>&) { return value(); }
};
template<class ContainerAllocator>
struct Definition< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> >
{
static const char* value()
{
return "float32 width\n"
"float32 max_width\n"
"bool is_grasped\n"
"uint16 temperature\n"
"uint64 duration_ms\n"
;
}
static const char* value(const ::sas_robot_driver_franka::GripperState_<ContainerAllocator>&) { return value(); }
};
} // namespace message_traits
} // namespace ros
namespace ros
{
namespace serialization
{
template<class ContainerAllocator> struct Serializer< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> >
{
template<typename Stream, typename T> inline static void allInOne(Stream& stream, T m)
{
stream.next(m.width);
stream.next(m.max_width);
stream.next(m.is_grasped);
stream.next(m.temperature);
stream.next(m.duration_ms);
}
ROS_DECLARE_ALLINONE_SERIALIZER
}; // struct GripperState_
} // namespace serialization
} // namespace ros
namespace ros
{
namespace message_operations
{
template<class ContainerAllocator>
struct Printer< ::sas_robot_driver_franka::GripperState_<ContainerAllocator> >
{
template<typename Stream> static void stream(Stream& s, const std::string& indent, const ::sas_robot_driver_franka::GripperState_<ContainerAllocator>& v)
{
s << indent << "width: ";
Printer<float>::stream(s, indent + " ", v.width);
s << indent << "max_width: ";
Printer<float>::stream(s, indent + " ", v.max_width);
s << indent << "is_grasped: ";
Printer<uint8_t>::stream(s, indent + " ", v.is_grasped);
s << indent << "temperature: ";
Printer<uint16_t>::stream(s, indent + " ", v.temperature);
s << indent << "duration_ms: ";
Printer<uint64_t>::stream(s, indent + " ", v.duration_ms);
}
};
} // namespace message_operations
} // namespace ros
#endif // SAS_ROBOT_DRIVER_FRANKA_MESSAGE_GRIPPERSTATE_H

View File

@@ -1,123 +0,0 @@
// Generated by gencpp from file sas_robot_driver_franka/Move.msg
// DO NOT EDIT!
#ifndef SAS_ROBOT_DRIVER_FRANKA_MESSAGE_MOVE_H
#define SAS_ROBOT_DRIVER_FRANKA_MESSAGE_MOVE_H
#include <ros/service_traits.h>
#include <sas_robot_driver_franka/MoveRequest.h>
#include <sas_robot_driver_franka/MoveResponse.h>
namespace sas_robot_driver_franka
{
struct Move
{
typedef MoveRequest Request;
typedef MoveResponse Response;
Request request;
Response response;
typedef Request RequestType;
typedef Response ResponseType;
}; // struct Move
} // namespace sas_robot_driver_franka
namespace ros
{
namespace service_traits
{
template<>
struct MD5Sum< ::sas_robot_driver_franka::Move > {
static const char* value()
{
return "73e650ba1526b28d9e3f1be7ee33a441";
}
static const char* value(const ::sas_robot_driver_franka::Move&) { return value(); }
};
template<>
struct DataType< ::sas_robot_driver_franka::Move > {
static const char* value()
{
return "sas_robot_driver_franka/Move";
}
static const char* value(const ::sas_robot_driver_franka::Move&) { return value(); }
};
// service_traits::MD5Sum< ::sas_robot_driver_franka::MoveRequest> should match
// service_traits::MD5Sum< ::sas_robot_driver_franka::Move >
template<>
struct MD5Sum< ::sas_robot_driver_franka::MoveRequest>
{
static const char* value()
{
return MD5Sum< ::sas_robot_driver_franka::Move >::value();
}
static const char* value(const ::sas_robot_driver_franka::MoveRequest&)
{
return value();
}
};
// service_traits::DataType< ::sas_robot_driver_franka::MoveRequest> should match
// service_traits::DataType< ::sas_robot_driver_franka::Move >
template<>
struct DataType< ::sas_robot_driver_franka::MoveRequest>
{
static const char* value()
{
return DataType< ::sas_robot_driver_franka::Move >::value();
}
static const char* value(const ::sas_robot_driver_franka::MoveRequest&)
{
return value();
}
};
// service_traits::MD5Sum< ::sas_robot_driver_franka::MoveResponse> should match
// service_traits::MD5Sum< ::sas_robot_driver_franka::Move >
template<>
struct MD5Sum< ::sas_robot_driver_franka::MoveResponse>
{
static const char* value()
{
return MD5Sum< ::sas_robot_driver_franka::Move >::value();
}
static const char* value(const ::sas_robot_driver_franka::MoveResponse&)
{
return value();
}
};
// service_traits::DataType< ::sas_robot_driver_franka::MoveResponse> should match
// service_traits::DataType< ::sas_robot_driver_franka::Move >
template<>
struct DataType< ::sas_robot_driver_franka::MoveResponse>
{
static const char* value()
{
return DataType< ::sas_robot_driver_franka::Move >::value();
}
static const char* value(const ::sas_robot_driver_franka::MoveResponse&)
{
return value();
}
};
} // namespace service_traits
} // namespace ros
#endif // SAS_ROBOT_DRIVER_FRANKA_MESSAGE_MOVE_H

View File

@@ -1,205 +0,0 @@
// Generated by gencpp from file sas_robot_driver_franka/MoveRequest.msg
// DO NOT EDIT!
#ifndef SAS_ROBOT_DRIVER_FRANKA_MESSAGE_MOVEREQUEST_H
#define SAS_ROBOT_DRIVER_FRANKA_MESSAGE_MOVEREQUEST_H
#include <string>
#include <vector>
#include <memory>
#include <ros/types.h>
#include <ros/serialization.h>
#include <ros/builtin_message_traits.h>
#include <ros/message_operations.h>
namespace sas_robot_driver_franka
{
template <class ContainerAllocator>
struct MoveRequest_
{
typedef MoveRequest_<ContainerAllocator> Type;
MoveRequest_()
: width(0.0)
, speed(0.0) {
}
MoveRequest_(const ContainerAllocator& _alloc)
: width(0.0)
, speed(0.0) {
(void)_alloc;
}
typedef float _width_type;
_width_type width;
typedef float _speed_type;
_speed_type speed;
typedef boost::shared_ptr< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> > Ptr;
typedef boost::shared_ptr< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> const> ConstPtr;
}; // struct MoveRequest_
typedef ::sas_robot_driver_franka::MoveRequest_<std::allocator<void> > MoveRequest;
typedef boost::shared_ptr< ::sas_robot_driver_franka::MoveRequest > MoveRequestPtr;
typedef boost::shared_ptr< ::sas_robot_driver_franka::MoveRequest const> MoveRequestConstPtr;
// constants requiring out of line definition
template<typename ContainerAllocator>
std::ostream& operator<<(std::ostream& s, const ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> & v)
{
ros::message_operations::Printer< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> >::stream(s, "", v);
return s;
}
template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator==(const ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator1> & lhs, const ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator2> & rhs)
{
return lhs.width == rhs.width &&
lhs.speed == rhs.speed;
}
template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator!=(const ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator1> & lhs, const ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator2> & rhs)
{
return !(lhs == rhs);
}
} // namespace sas_robot_driver_franka
namespace ros
{
namespace message_traits
{
template <class ContainerAllocator>
struct IsMessage< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> >
: TrueType
{ };
template <class ContainerAllocator>
struct IsMessage< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> const>
: TrueType
{ };
template <class ContainerAllocator>
struct IsFixedSize< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> >
: TrueType
{ };
template <class ContainerAllocator>
struct IsFixedSize< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> const>
: TrueType
{ };
template <class ContainerAllocator>
struct HasHeader< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> >
: FalseType
{ };
template <class ContainerAllocator>
struct HasHeader< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> const>
: FalseType
{ };
template<class ContainerAllocator>
struct MD5Sum< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> >
{
static const char* value()
{
return "b2d4f46fe020a06d64128c90310c767d";
}
static const char* value(const ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator>&) { return value(); }
static const uint64_t static_value1 = 0xb2d4f46fe020a06dULL;
static const uint64_t static_value2 = 0x64128c90310c767dULL;
};
template<class ContainerAllocator>
struct DataType< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> >
{
static const char* value()
{
return "sas_robot_driver_franka/MoveRequest";
}
static const char* value(const ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator>&) { return value(); }
};
template<class ContainerAllocator>
struct Definition< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> >
{
static const char* value()
{
return "float32 width\n"
"float32 speed\n"
;
}
static const char* value(const ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator>&) { return value(); }
};
} // namespace message_traits
} // namespace ros
namespace ros
{
namespace serialization
{
template<class ContainerAllocator> struct Serializer< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> >
{
template<typename Stream, typename T> inline static void allInOne(Stream& stream, T m)
{
stream.next(m.width);
stream.next(m.speed);
}
ROS_DECLARE_ALLINONE_SERIALIZER
}; // struct MoveRequest_
} // namespace serialization
} // namespace ros
namespace ros
{
namespace message_operations
{
template<class ContainerAllocator>
struct Printer< ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator> >
{
template<typename Stream> static void stream(Stream& s, const std::string& indent, const ::sas_robot_driver_franka::MoveRequest_<ContainerAllocator>& v)
{
s << indent << "width: ";
Printer<float>::stream(s, indent + " ", v.width);
s << indent << "speed: ";
Printer<float>::stream(s, indent + " ", v.speed);
}
};
} // namespace message_operations
} // namespace ros
#endif // SAS_ROBOT_DRIVER_FRANKA_MESSAGE_MOVEREQUEST_H

View File

@@ -1,195 +0,0 @@
// Generated by gencpp from file sas_robot_driver_franka/MoveResponse.msg
// DO NOT EDIT!
#ifndef SAS_ROBOT_DRIVER_FRANKA_MESSAGE_MOVERESPONSE_H
#define SAS_ROBOT_DRIVER_FRANKA_MESSAGE_MOVERESPONSE_H
#include <string>
#include <vector>
#include <memory>
#include <ros/types.h>
#include <ros/serialization.h>
#include <ros/builtin_message_traits.h>
#include <ros/message_operations.h>
namespace sas_robot_driver_franka
{
template <class ContainerAllocator>
struct MoveResponse_
{
typedef MoveResponse_<ContainerAllocator> Type;
MoveResponse_()
: success(false) {
}
MoveResponse_(const ContainerAllocator& _alloc)
: success(false) {
(void)_alloc;
}
typedef uint8_t _success_type;
_success_type success;
typedef boost::shared_ptr< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> > Ptr;
typedef boost::shared_ptr< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> const> ConstPtr;
}; // struct MoveResponse_
typedef ::sas_robot_driver_franka::MoveResponse_<std::allocator<void> > MoveResponse;
typedef boost::shared_ptr< ::sas_robot_driver_franka::MoveResponse > MoveResponsePtr;
typedef boost::shared_ptr< ::sas_robot_driver_franka::MoveResponse const> MoveResponseConstPtr;
// constants requiring out of line definition
template<typename ContainerAllocator>
std::ostream& operator<<(std::ostream& s, const ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> & v)
{
ros::message_operations::Printer< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> >::stream(s, "", v);
return s;
}
template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator==(const ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator1> & lhs, const ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator2> & rhs)
{
return lhs.success == rhs.success;
}
template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator!=(const ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator1> & lhs, const ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator2> & rhs)
{
return !(lhs == rhs);
}
} // namespace sas_robot_driver_franka
namespace ros
{
namespace message_traits
{
template <class ContainerAllocator>
struct IsMessage< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> >
: TrueType
{ };
template <class ContainerAllocator>
struct IsMessage< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> const>
: TrueType
{ };
template <class ContainerAllocator>
struct IsFixedSize< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> >
: TrueType
{ };
template <class ContainerAllocator>
struct IsFixedSize< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> const>
: TrueType
{ };
template <class ContainerAllocator>
struct HasHeader< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> >
: FalseType
{ };
template <class ContainerAllocator>
struct HasHeader< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> const>
: FalseType
{ };
template<class ContainerAllocator>
struct MD5Sum< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> >
{
static const char* value()
{
return "358e233cde0c8a8bcfea4ce193f8fc15";
}
static const char* value(const ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator>&) { return value(); }
static const uint64_t static_value1 = 0x358e233cde0c8a8bULL;
static const uint64_t static_value2 = 0xcfea4ce193f8fc15ULL;
};
template<class ContainerAllocator>
struct DataType< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> >
{
static const char* value()
{
return "sas_robot_driver_franka/MoveResponse";
}
static const char* value(const ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator>&) { return value(); }
};
template<class ContainerAllocator>
struct Definition< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> >
{
static const char* value()
{
return "bool success\n"
;
}
static const char* value(const ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator>&) { return value(); }
};
} // namespace message_traits
} // namespace ros
namespace ros
{
namespace serialization
{
template<class ContainerAllocator> struct Serializer< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> >
{
template<typename Stream, typename T> inline static void allInOne(Stream& stream, T m)
{
stream.next(m.success);
}
ROS_DECLARE_ALLINONE_SERIALIZER
}; // struct MoveResponse_
} // namespace serialization
} // namespace ros
namespace ros
{
namespace message_operations
{
template<class ContainerAllocator>
struct Printer< ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator> >
{
template<typename Stream> static void stream(Stream& s, const std::string& indent, const ::sas_robot_driver_franka::MoveResponse_<ContainerAllocator>& v)
{
s << indent << "success: ";
Printer<uint8_t>::stream(s, indent + " ", v.success);
}
};
} // namespace message_operations
} // namespace ros
#endif // SAS_ROBOT_DRIVER_FRANKA_MESSAGE_MOVERESPONSE_H

View File

@@ -0,0 +1,139 @@
/*
# Copyright (c) 2023 Juan Jose Quiroz Omana
#
# This file is part of sas_robot_driver_franka.
#
# sas_robot_driver_franka is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sas_robot_driver_franka is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with sas_robot_driver. If not, see <https://www.gnu.org/licenses/>.
#
# ################################################################
#
# Author: Juan Jose Quiroz Omana, email: juanjqogm@gmail.com
#
# ################################################################
#
# Contributors:
# 1. Juan Jose Quiroz Omana (juanjqogm@gmail.com)
# - Adapted from sas_robot_driver_denso.cpp
# (https://github.com/SmartArmStack/sas_robot_driver_denso/blob/master/src/sas_robot_driver_denso.cpp)
#
# ################################################################
*/
#pragma once
#include <exception>
#include <tuple>
#include <atomic>
#include <vector>
#include <memory>
#include <dqrobotics/DQ.h>
#include <sas_core/sas_clock.hpp>
// #include <dqrobotics/interfaces/vrep/DQ_VrepRobot.h>
#include <dqrobotics/interfaces/vrep/DQ_VrepInterface.h>
#include <dqrobotics/interfaces/json11/DQ_JsonReader.h>
// #include <dqrobotics/robot_modeling/DQ_SerialManipulatorDH.h>
#include <thread>
#include <atomic>
#include <sas_robot_driver/sas_robot_driver_server.hpp>
#include <sas_robot_driver/sas_robot_driver_client.hpp>
#define VIRTUAL_ROBOT_SIMULATION_SAMPLING_TIME_SEC 0.002 // 2ms, 500Hz
#define REAL_ROBOT_INTERFACE_INIT_TIMEOUT_COUNT 500
using namespace DQ_robotics;
using namespace Eigen;
namespace qros
{
struct RobotDriverCoppeliaConfiguration
{
double thread_sampling_time_sec; // frontend vrep update rate
int vrep_port;
std::string vrep_ip;
std::vector<std::string> vrep_joint_names;
bool vrep_dynamically_enabled = false;
std::string robot_mode;
bool using_real_robot;
std::string robot_topic_prefix;
std::string robot_parameter_file_path;
// VectorXd q_min;
// VectorXd q_max;
};
class RobotDriverCoppelia
{
private:
enum ControlMode{
Position=0,
Velocity
};
RobotDriverCoppeliaConfiguration configuration_;
std::shared_ptr<Node> node_sptr_;
sas::Clock clock_;
std::atomic_bool* break_loops_;
bool _should_shutdown() const {return (*break_loops_);}
ControlMode robot_mode_;
std::shared_ptr<DQ_VrepInterface> vi_;
std::shared_ptr<sas::RobotDriverClient> real_robot_interface_ = nullptr;
std::shared_ptr<sas::RobotDriverServer> robot_provider_ = nullptr;
// backend thread for simulaton
/**
* Current simulation mechanism is not accounting for any robot dynamics, just the joint limits
*/
std::thread velocity_control_simulation_thread_;
VectorXd simulated_joint_positions_;
VectorXd simulated_joint_velocities_;
void start_simulation_thread(); // thread entry point
void _velocity_control_simulation_thread_main();
std::atomic_bool simulation_thread_started_{false};
bool initialized_ = false;
inline void _assert_initialized() const{
if (!initialized_){throw std::runtime_error("[RobotDriverCoppelia] Robot driver not initialized");}
}
inline void _assert_is_alive() const{
if(!configuration_.using_real_robot && !simulation_thread_started_){throw std::runtime_error("[RobotDriverCoppelia] Robot Simulation is not alive");}
}
void _start_control_loop();
protected:
inline void _update_vrep_position(const VectorXd &joint_positions, const bool& force_update=false) const;
inline void _update_vrep_velocity(const VectorXd & joint_velocity) const;
public:
RobotDriverCoppelia(const RobotDriverCoppelia&)=delete;
RobotDriverCoppelia()=delete;
~RobotDriverCoppelia();
RobotDriverCoppelia(const std::shared_ptr<Node> &node_sptr, const RobotDriverCoppeliaConfiguration& configuration, std::atomic_bool* break_loops);
int start_control_loop(); // public entry point
void connect();
void disconnect();
void initialize();
void deinitialize();
std::tuple<VectorXd, VectorXd> joint_limits_;
};
}

View File

@@ -32,13 +32,13 @@
#pragma once #pragma once
#include <array> #include <array>
#include <Eigen/Core> #include <eigen3/Eigen/Core>
#include <Eigen/Dense> #include <eigen3/Eigen/Dense>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <dqrobotics/solvers/DQ_QPOASESSolver.h> #include <dqrobotics/solvers/DQ_QPOASESSolver.h>
#include <memory> #include <memory>
#include "constraints_manager.h" #include <constraints_manager.h>
using namespace DQ_robotics; using namespace DQ_robotics;

View File

@@ -4,8 +4,8 @@
#include <array> #include <array>
#include <Eigen/Core> #include <eigen3/Eigen/Core>
#include <Eigen/Dense> #include <eigen3/Eigen/Dense>
#include <franka/control_types.h> #include <franka/control_types.h>
#include <franka/duration.h> #include <franka/duration.h>
#include <franka/robot.h> #include <franka/robot.h>

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <array> #include <array>
#include <Eigen/Core> #include <eigen3/Eigen/Core>
#include <Eigen/Dense> #include <eigen3/Eigen/Dense>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <dqrobotics/solvers/DQ_QPOASESSolver.h> #include <dqrobotics/solvers/DQ_QPOASESSolver.h>

View File

@@ -42,21 +42,26 @@
// #define IN_TESTING // #define IN_TESTING
// #include <sas_robot_driver/sas_robot_driver.h> // #include <sas_robot_driver/sas_robot_driver.h>
#include <sas_clock/sas_clock.h> #include <sas_core/sas_clock.hpp>
#include <ros/ros.h>
#include <ros/service.h> #include <rclcpp/service.hpp>
#include <sas_robot_driver_franka/Grasp.h> #include <rclcpp/rclcpp.hpp>
#include <sas_robot_driver_franka/Move.h>
#include <sas_robot_driver_franka/GripperState.h>
#ifdef IN_TESTING #ifdef IN_TESTING
#include <Move.h> // dummy include #include "local/srv/grasp.hpp"
#include <Grasp.h> // dummy include #include "local/srv/move.hpp"
#include <GripperState.h> // dummy include #include "local/msg/gripper_state.hpp"
#else
#include <sas_robot_driver_franka_interfaces/srv/grasp.hpp>
#include <sas_robot_driver_franka_interfaces/srv/move.hpp>
#include <sas_robot_driver_franka_interfaces/msg/gripper_state.hpp>
#endif #endif
// using namespace DQ_robotics; // using namespace DQ_robotics;
// using namespace Eigen; // using namespace Eigen;
using namespace rclcpp;
using namespace sas_robot_driver_franka_interfaces;
namespace qros { namespace qros {
@@ -64,7 +69,7 @@ namespace qros {
struct EffectorDriverFrankaHandConfiguration struct EffectorDriverFrankaHandConfiguration
{ {
std::string robot_ip; std::string robot_ip;
int thread_sampeling_time_ns = 1e8; // 10Hz double thread_sampeling_time_s = 1e8; // 10Hz
double default_force = 3.0; double default_force = 3.0;
double default_speed = 0.1; double default_speed = 0.1;
double default_epsilon_inner = 0.005; double default_epsilon_inner = 0.005;
@@ -75,7 +80,7 @@ class EffectorDriverFrankaHand{
private: private:
std::string driver_node_prefix_; std::string driver_node_prefix_;
EffectorDriverFrankaHandConfiguration configuration_; EffectorDriverFrankaHandConfiguration configuration_;
ros::NodeHandle& node_handel_; std::shared_ptr<Node> node_;
std::shared_ptr<franka::Gripper> gripper_sptr_; std::shared_ptr<franka::Gripper> gripper_sptr_;
@@ -88,17 +93,24 @@ private:
void _gripper_status_loop(); void _gripper_status_loop();
std::thread status_loop_thread_; std::thread status_loop_thread_;
std::atomic_bool status_loop_running_{false}; std::atomic_bool status_loop_running_{false};
ros::Publisher gripper_status_publisher_;
Publisher<msg::GripperState>::SharedPtr gripper_status_publisher_;
std::mutex gripper_in_use_; std::mutex gripper_in_use_;
ros::ServiceServer grasp_server_; Service<srv::Grasp>::SharedPtr grasp_srv_;
ros::ServiceServer move_server_; Service<srv::Move>::SharedPtr move_srv_;
public: public:
bool _grasp_srv_callback(sas_robot_driver_franka::Grasp::Request& req, sas_robot_driver_franka::Grasp::Response& res); bool _grasp_srv_callback(
const std::shared_ptr<srv::Grasp::Request> req,
std::shared_ptr<srv::Grasp::Response> res
);
bool _move_srv_callback(sas_robot_driver_franka::Move::Request& req, sas_robot_driver_franka::Move::Response& res); bool _move_srv_callback(
const std::shared_ptr<srv::Move::Request> req,
std::shared_ptr<srv::Move::Response> res
);
EffectorDriverFrankaHand(const EffectorDriverFrankaHand&)=delete; EffectorDriverFrankaHand(const EffectorDriverFrankaHand&)=delete;
EffectorDriverFrankaHand()=delete; EffectorDriverFrankaHand()=delete;
@@ -107,7 +119,7 @@ public:
EffectorDriverFrankaHand( EffectorDriverFrankaHand(
const std::string &driver_node_prefix, const std::string &driver_node_prefix,
const EffectorDriverFrankaHandConfiguration& configuration, const EffectorDriverFrankaHandConfiguration& configuration,
ros::NodeHandle& node_handel, std::shared_ptr<Node> node,
std::atomic_bool* break_loops); std::atomic_bool* break_loops);
void start_control_loop(); void start_control_loop();

View File

@@ -40,12 +40,12 @@
#include <franka/robot.h> #include <franka/robot.h>
#include <franka/gripper.h> #include <franka/gripper.h>
#include <franka/exception.h> #include <franka/exception.h>
#include "generator/motion_generator.h" #include <sas_robot_driver_franka/generator/motion_generator.h>
#include <sas_robot_driver_franka/generator/quadratic_program_motion_generator.h>
#include <sas_robot_driver_franka/generator/custom_motion_generation.h>
#include <thread> #include <thread>
#include "generator/quadratic_program_motion_generator.h"
#include <dqrobotics/robots/FrankaEmikaPandaRobot.h> #include <dqrobotics/robots/FrankaEmikaPandaRobot.h>
#include <atomic> #include <atomic>
#include "generator/custom_motion_generation.h"
using namespace DQ_robotics; using namespace DQ_robotics;
using namespace Eigen; using namespace Eigen;

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
/* /*
# Copyright (c) 2023 Juan Jose Quiroz Omana # Copyright (c) 2024 Quenitin Lin
# #
# This file is part of sas_robot_driver_franka. # This file is part of sas_robot_driver_franka.
# #
@@ -28,63 +28,66 @@
# #
# ################################################################ # ################################################################
*/ */
#include <ros/ros.h>
#include <ros/node_handle.h> #include <rclcpp/rclcpp.hpp>
#include <sas_common/sas_common.h> #include <rclcpp/node.hpp>
#include <sas_conversions/sas_conversions.h> // #include <sas_common/sas_common.hpp>
#include <geometry_msgs/WrenchStamped.h> #include <sas_conversions/sas_conversions.hpp>
#include <geometry_msgs/Transform.h> #include <geometry_msgs/msg/wrench_stamped.hpp>
#include <geometry_msgs/TransformStamped.h> #include <geometry_msgs/msg/transform.hpp>
#include <geometry_msgs/msg/transform_stamped.hpp>
#include <tf2_ros/transform_listener.h> #include <tf2_ros/transform_listener.h>
#include <tf2_geometry_msgs/tf2_geometry_msgs.h> #include <tf2_ros/buffer.h>
#include <geometry_msgs/Pose.h> #include <tf2/time.h>
#include <std_msgs/Header.h> // #include <tf2_geometry_msgs/tf2_geometry_msgs.h>
#include <geometry_msgs/msg/pose.hpp>
#include <std_msgs/msg/header.hpp>
#include <dqrobotics/DQ.h> #include <dqrobotics/DQ.h>
#define BUFFER_DURATION_DEFAULT_S 2.0 // 2 second #define BUFFER_DURATION_DEFAULT_S 2.0 // 2 second
using namespace rclcpp;
namespace qros { namespace qros {
using namespace DQ_robotics; using namespace DQ_robotics;
class RobotDynamicInterface { class RobotDynamicsClient {
private: private:
unsigned int seq_ = 0; std::shared_ptr<Node> node_;
std::string node_prefix_; std::string topic_prefix_;
std::string child_frame_id_; std::string child_frame_id_;
std::string parent_frame_id_; std::string parent_frame_id_;
ros::Subscriber subscriber_cartesian_stiffness_; Subscription<geometry_msgs::msg::WrenchStamped>::SharedPtr subscriber_cartesian_stiffness_;
tf2_ros::Buffer tf_buffer_; std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
tf2_ros::TransformListener tf_listener_; std::shared_ptr<tf2_ros::TransformListener> tf_listener_;
static geometry_msgs::Transform _dq_to_geometry_msgs_transform(const DQ& pose) ; static geometry_msgs::msg::Transform _dq_to_geometry_msgs_transform(const DQ& pose) ;
Vector3d last_stiffness_force_; Vector3d last_stiffness_force_;
Vector3d last_stiffness_torque_; Vector3d last_stiffness_torque_;
DQ last_stiffness_frame_pose_; DQ last_stiffness_frame_pose_;
void _callback_cartesian_stiffness(const geometry_msgs::WrenchStampedConstPtr &msg); void _callback_cartesian_stiffness(const geometry_msgs::msg::WrenchStamped &msg);
static DQ _geometry_msgs_transform_to_dq(const geometry_msgs::Transform& transform); static DQ _geometry_msgs_transform_to_dq(const geometry_msgs::msg::Transform& transform);
public: public:
RobotDynamicInterface() = delete; RobotDynamicsClient() = delete;
RobotDynamicInterface(const RobotDynamicInterface&) = delete; RobotDynamicsClient(const RobotDynamicsClient&) = delete;
#ifdef BUILD_PYBIND // #ifdef BUILD_PYBIND
explicit RobotDynamicInterface(const std::string& node_prefix):RobotDynamicInterface(sas::common::get_static_node_handle(),node_prefix){} // explicit RobotDynamicsClient(const std::string& node_prefix):RobotDynamicsClient(sas::common::get_static_node_handle(),node_prefix){}
#endif // #endif
explicit RobotDynamicInterface(ros::NodeHandle& nodehandle, const std::string& node_prefix=ros::this_node::getName()); explicit RobotDynamicsClient(const std::shared_ptr<Node> &node, const std::string& topic_prefix="GET_FROM_NODE");
RobotDynamicInterface(ros::NodeHandle& publisher_nodehandle, ros::NodeHandle& subscriber_nodehandle, const std::string& node_prefix=ros::this_node::getName());
VectorXd get_stiffness_force(); VectorXd get_stiffness_force();
VectorXd get_stiffness_torque(); VectorXd get_stiffness_torque();
DQ get_stiffness_frame_pose(); DQ get_stiffness_frame_pose();
bool is_enabled() const; bool is_enabled() const;
std::string get_topic_prefix() const {return node_prefix_;} std::string get_topic_prefix() const {return topic_prefix_;}
}; };

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
/* /*
# Copyright (c) 2023 Juan Jose Quiroz Omana # Copyright (c) 2024 Quenitin Lin
# #
# This file is part of sas_robot_driver_franka. # This file is part of sas_robot_driver_franka.
# #
@@ -28,60 +28,60 @@
# #
# ################################################################ # ################################################################
*/ */
#include <ros/ros.h> #include <rclcpp/rclcpp.hpp>
#include <ros/node_handle.h> #include <rclcpp/node.hpp>
#include <sas_common/sas_common.h> // #include <sas_common/sas_common.hpp>
#include <sas_conversions/sas_conversions.h> #include <sas_conversions/sas_conversions.hpp>
#include <geometry_msgs/WrenchStamped.h> #include <geometry_msgs/msg/wrench_stamped.hpp>
#include <geometry_msgs/Transform.h> #include <geometry_msgs/msg/transform.hpp>
#include <geometry_msgs/TransformStamped.h> #include <geometry_msgs/msg/transform_stamped.hpp>
#include <tf2_ros/transform_broadcaster.h> #include <tf2_ros/transform_broadcaster.h>
#include <tf2_ros//static_transform_broadcaster.h> #include <tf2_ros//static_transform_broadcaster.h>
#include <tf2_geometry_msgs/tf2_geometry_msgs.h> #include <geometry_msgs/msg/pose.hpp>
#include <geometry_msgs/Pose.h> #include <std_msgs/msg/header.hpp>
#include <std_msgs/Header.h>
#include <dqrobotics/DQ.h> #include <dqrobotics/DQ.h>
#define REDUCE_TF_PUBLISH_RATE 10 #define REDUCE_TF_PUBLISH_RATE 10
#define WORLD_FRAME_ID "world" #define WORLD_FRAME_ID "world"
using namespace rclcpp;
namespace qros { namespace qros {
using namespace DQ_robotics; using namespace DQ_robotics;
class RobotDynamicProvider { class RobotDynamicsServer {
private: private:
unsigned int seq_ = 0; unsigned int seq_ = 0;
std::shared_ptr<Node> node_;
std::string node_prefix_; std::string topic_prefix_;
std::string child_frame_id_; std::string child_frame_id_;
std::string parent_frame_id_; std::string parent_frame_id_;
ros::Publisher publisher_cartesian_stiffness_; rclcpp::Publisher<geometry_msgs::msg::WrenchStamped>::SharedPtr publisher_cartesian_stiffness_;
tf2_ros::TransformBroadcaster tf_broadcaster_; std::shared_ptr<tf2_ros::TransformBroadcaster> tf_broadcaster_;
tf2_ros::StaticTransformBroadcaster static_base_tf_broadcaster_; std::shared_ptr<tf2_ros::StaticTransformBroadcaster> static_base_tf_broadcaster_;
DQ world_to_base_tf_; DQ world_to_base_tf_ = DQ(0);
static geometry_msgs::Transform _dq_to_geometry_msgs_transform(const DQ& pose); static geometry_msgs::msg::Transform _dq_to_geometry_msgs_transform(const DQ& pose);
void _publish_base_static_tf(); void _publish_base_static_tf();
public: public:
RobotDynamicProvider() = delete; RobotDynamicsServer() = delete;
RobotDynamicProvider(const RobotDynamicProvider&) = delete; RobotDynamicsServer(const RobotDynamicsServer&) = delete;
#ifdef BUILD_PYBIND // #ifdef BUILD_PYBIND
explicit RobotDynamicProvider(const std::string& node_prefix):RobotDynamicProvider(sas::common::get_static_node_handle(),node_prefix){} // explicit RobotDynamicsServer(const std::string& node_prefix):RobotDynamicsServer(sas::common::get_static_node_handle(),node_prefix){}
#endif // #endif
explicit RobotDynamicProvider(ros::NodeHandle& nodehandle, const std::string& node_prefix=ros::this_node::getName()); explicit RobotDynamicsServer(const std::shared_ptr<Node> &node, const std::string& topic_prefix="GET_FROM_NODE");
RobotDynamicProvider(ros::NodeHandle& publisher_nodehandle, ros::NodeHandle& subscriber_nodehandle, const std::string& node_prefix=ros::this_node::getName());
void publish_stiffness(const DQ& base_to_stiffness, const Vector3d& force, const Vector3d& torque); void publish_stiffness(const DQ& base_to_stiffness, const Vector3d& force, const Vector3d& torque);
void set_world_to_base_tf(const DQ& world_to_base_tf); void set_world_to_base_tf(const DQ& world_to_base_tf);
bool is_enabled() const; bool is_enabled() const;
std::string get_topic_prefix() const {return node_prefix_;} std::string get_topic_prefix() const {return topic_prefix_;}
}; };

View File

@@ -40,10 +40,10 @@
#include <dqrobotics/DQ.h> #include <dqrobotics/DQ.h>
#include <sas_robot_driver/sas_robot_driver.h> #include <sas_core/sas_robot_driver.hpp>
#include "robot_interface_franka.h" #include <sas_robot_driver_franka/interfaces/robot_interface_franka.hpp>
#include <ros/common.h> #include <rclcpp/rclcpp.hpp>
#include <robot_dynamic/qros_robot_dynamics_provider.h> #include <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_server.hpp>
using namespace DQ_robotics; using namespace DQ_robotics;
using namespace Eigen; using namespace Eigen;
@@ -64,14 +64,16 @@ struct RobotDriverFrankaConfiguration
}; };
class RobotDriverFranka: public RobotDriver class RobotDriverFranka: public sas::RobotDriver
{ {
private: private:
std::shared_ptr<Node> node_;
RobotDriverFrankaConfiguration configuration_; RobotDriverFrankaConfiguration configuration_;
std::shared_ptr<RobotInterfaceFranka> robot_driver_interface_sptr_ = nullptr; std::shared_ptr<RobotInterfaceFranka> robot_driver_interface_sptr_ = nullptr;
qros::RobotDynamicProvider* robot_dynamic_provider_; std::shared_ptr<qros::RobotDynamicsServer> robot_dynamic_provider_sptr_;
//Joint positions //Joint positions
VectorXd joint_positions_; VectorXd joint_positions_;
@@ -98,7 +100,8 @@ public:
~RobotDriverFranka(); ~RobotDriverFranka();
RobotDriverFranka( RobotDriverFranka(
qros::RobotDynamicProvider* robot_dynamic_provider, const std::shared_ptr<Node> &node,
const std::shared_ptr<qros::RobotDynamicsServer> &robot_dynamic_provider,
const RobotDriverFrankaConfiguration& configuration, const RobotDriverFrankaConfiguration& configuration,
std::atomic_bool* break_loops std::atomic_bool* break_loops
); );

View File

@@ -0,0 +1,45 @@
from launch import LaunchDescription
from launch_ros.actions import Node
import os
def generate_launch_description():
return LaunchDescription([
Node(
package='sas_robot_driver_franka',
executable='sas_robot_driver_franka_node',
name='arm3',
parameters=[{
"robot_ip_address": "172.16.0.4",
"thread_sampling_time_sec": 0.004,
# "thread_sampling_time_nsec": 4000000,
"q_min": [-2.3093, -1.5133, -2.4937, -2.7478, -2.4800, 0.8521, -2.6895],
"q_max": [2.3093, 1.5133, 2.4937, -0.4461, 2.4800, 4.2094, 2.6895],
"force_upper_limits_scaling_factor": 4.0,
"upper_torque_threshold": [40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0],
"upper_force_threshold": [40.0, 40.0, 40.0, 40.0, 40.0, 40.0],
"robot_mode": "VelocityControl",
"robot_parameter_file_path": os.environ["ROBOT_3_JSON_PATH"]
}],
output="screen"
),
Node(
package='sas_robot_driver_franka',
executable='sas_robot_driver_franka_coppelia_node',
name='arm3_coppelia',
parameters=[{
"thread_sampling_time_sec": 0.008,
"vrep_ip": os.environ["VREP_IP"],
"vrep_port": 20012,
"vrep_dynamically_enabled": True,
"using_real_robot": True,
"vrep_joint_names": ["Franka_joint1#1", "Franka_joint2#1", "Franka_joint3#1", "Franka_joint4#1",
"Franka_joint5#1", "Franka_joint6#1", "Franka_joint7#1"],
"robot_topic_prefix": "/arm3",
"robot_mode": "VelocityControl",
"robot_parameter_file_path": os.environ["ROBOT_3_JSON_PATH"]
}],
output="screen"
),
])

View File

@@ -0,0 +1,24 @@
from launch import LaunchDescription
from launch_ros.actions import Node
import os
def generate_launch_description():
return LaunchDescription([
Node(
package='sas_robot_driver_franka',
executable='sas_robot_driver_franka_hand_node',
name='arm3_hand',
parameters=[{
"robot_ip_address": "172.16.0.2",
# "thread_sampling_time_nsec": 20000000, # 20ms , 50Hz
"thread_sampling_time_sec": 0.02,
"default_force": 2.0,
"default_speed": 0.07,
"default_epsilon_inner": 0.007,
"default_epsilon_outer": 0.007,
}],
output="screen"
),
])

View File

@@ -0,0 +1,27 @@
from launch import LaunchDescription
from launch_ros.actions import Node
import os
def generate_launch_description():
return LaunchDescription([
Node(
package='sas_robot_driver_franka',
executable='sas_robot_driver_franka_coppelia_node',
name='arm3_coppelia',
parameters=[{
"thread_sampling_time_sec": 0.008,
"vrep_ip": os.environ["VREP_IP"],
"vrep_port": 20012,
"vrep_dynamically_enabled": True,
"using_real_robot": False,
"vrep_joint_names": ["Franka_joint1#1", "Franka_joint2#1", "Franka_joint3#1", "Franka_joint4#1",
"Franka_joint5#1", "Franka_joint6#1", "Franka_joint7#1"],
"robot_topic_prefix": "/arm3",
"robot_mode": "VelocityControl",
"robot_parameter_file_path": os.environ["ROBOT_3_JSON_PATH"]
}],
output="screen"
),
])

View File

@@ -1,5 +0,0 @@
float32 width
float32 max_width
bool is_grasped
uint16 temperature
uint64 duration_ms

View File

@@ -1,94 +1,32 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<package format="2"> <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>sas_robot_driver_franka</name> <name>sas_robot_driver_franka</name>
<version>0.0.0</version> <version>0.0.0</version>
<description>The sas_driver_franka package</description> <description>The sas_driver_franka package</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="moonshot@todo.todo">moonshot</maintainer> <maintainer email="moonshot@todo.todo">moonshot</maintainer>
<license>LGPLv3</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<!-- One license tag required, multiple allowed, one license per tag --> <depend>rclcpp</depend>
<!-- Commonly used license strings: --> <depend>rclpy</depend>
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 --> <depend>tf2_ros</depend>
<license>TODO</license> <depend>tf2</depend>
<depend>std_msgs</depend>
<depend>sas_core</depend>
<depend>sas_robot_driver</depend>
<depend>sas_common</depend>
<depend>sas_robot_driver_franka_interface</depend>
<!-- Url tags are optional, but multiple are allowed, one per tag --> <test_depend>ament_lint_auto</test_depend>
<!-- Optional attribute type can be: website, bugtracker, or repository --> <test_depend>ament_lint_common</test_depend>
<!-- Example: --> <test_depend>ament_copyright</test_depend>
<!-- <url type="website">http://wiki.ros.org/sas_driver_franka</url> --> <test_depend>ament_flake8</test_depend>
<test_depend>ament_pep257</test_depend>
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->
<!-- <exec_depend>roscpp</exec_depend> -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>tf2_ros</build_depend>
<build_depend>tf2</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>sas_clock</build_depend>
<build_depend>sas_robot_driver</build_depend>
<build_depend>sas_common</build_depend>
<build_depend>sas_patient_side_manager</build_depend>
<build_depend>pybind11_catkin</build_depend>
<build_depend>message_generation</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>tf2_ros</build_export_depend>
<build_export_depend>tf2</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<build_export_depend>sas_clock</build_export_depend>
<build_export_depend>sas_robot_driver</build_export_depend>
<build_export_depend>sas_common</build_export_depend>
<build_export_depend>sas_patient_side_manager</build_export_depend>
<build_export_depend>pybind11_catkin</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>tf2_ros</exec_depend>
<exec_depend>tf2</exec_depend>
<exec_depend>std_msgs</exec_depend>
<exec_depend>sas_clock</exec_depend>
<exec_depend>sas_robot_driver</exec_depend>
<exec_depend>sas_common</exec_depend>
<exec_depend>sas_patient_side_manager</exec_depend>
<exec_depend>message_runtime</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export> <export>
<!-- Other tools can request additional information be placed here --> <build_type>ament_cmake</build_type>
</export> </export>
</package> </package>

View File

@@ -7,7 +7,7 @@
#include <QMainWindow> #include <QMainWindow>
#include "qspinbox.h" #include "qspinbox.h"
#include "robot_interface_franka.h" #include <sas_robot_driver_franka/interfaces/robot_interface_franka.hpp>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; } namespace Ui { class MainWindow; }

View File

@@ -1,9 +1,16 @@
import rospy """
from sas_robot_driver_franka.srv import Move, MoveRequest, MoveResponse, Grasp, GraspRequest, GraspResponse """
from sas_robot_driver_franka.msg import GripperState from sas_robot_driver_franka._qros_franka_robot_dynamic import RobotDynamicsClient, RobotDynamicsServer
import rclpy
from rclpy.node import Node
# from sas_common import rclcpp_init, rclcpp_Node, rclcpp_spin_some, rclcpp_shutdown
from sas_robot_driver_franka_interfaces.srv import Move, Move_Request, Move_Response, Grasp, Grasp_Request, Grasp_Response
from sas_robot_driver_franka_interfaces.msg import GripperState
import os import os
import threading import threading
from queue import Queue from queue import Queue
import time
import struct import struct
MOVE_TOPIC_SUFFIX = "move" MOVE_TOPIC_SUFFIX = "move"
@@ -16,14 +23,15 @@ class FrankaGripperInterface:
Non blocking interface to control the Franka gripper Non blocking interface to control the Franka gripper
""" """
def __init__(self, robot_prefix): def __init__(self, node: Node, robot_prefix):
self.robot_prefix = robot_prefix self.robot_prefix = robot_prefix
self.move_service = rospy.ServiceProxy(os.path.join(robot_prefix, MOVE_TOPIC_SUFFIX), Move) self.node = node
self.move_service = node.create_client(Move, os.path.join(robot_prefix, MOVE_TOPIC_SUFFIX))
self._moving = False self._moving = False
self.grasp_service = rospy.ServiceProxy(os.path.join(robot_prefix, GRASP_TOPIC_SUFFIX), Grasp) self.grasp_service = node.create_client(Grasp, os.path.join(robot_prefix, GRASP_TOPIC_SUFFIX))
self._grasping = False self._grasping = False
self.status_subscriber = rospy.Subscriber(os.path.join(robot_prefix, STATUS_TOPIC_SUFFIX), GripperState, self.status_subscriber = node.create_subscription(GripperState, os.path.join(robot_prefix, STATUS_TOPIC_SUFFIX),
self._status_callback) self._status_callback, 5)
self.result_queue = Queue() self.result_queue = Queue()
@@ -32,20 +40,29 @@ class FrankaGripperInterface:
self.state_max_width = None self.state_max_width = None
self.state_temperature = None self.state_temperature = None
self.state_is_grasped = None self.state_is_grasped = None
self.spin_handler = self._default_spin_handler
def _default_spin_handler(self):
rclpy.spin_once(self.node)
def set_spin_handler(self, spin_handler):
self.spin_handler = spin_handler
def _is_service_ready(self, service): def _is_service_ready(self, service):
try: try:
rospy.wait_for_service(service, timeout=0.1) self.node.get_logger().info("Waiting for service: " + service.service_name)
service.wait_for_service(timeout_sec=0.1)
return True return True
except rospy.ROSException: except Exception as e:
self.node.get_logger().info("Service error: " + service.service_name + ": " + str(e))
return False return False
def is_enabled(self): def is_enabled(self):
if self.state_width is None: if self.state_width is None:
return False return False
if not self._is_service_ready(self.move_service.resolved_name): if not self._is_service_ready(self.move_service):
return False return False
if not self._is_service_ready(self.grasp_service.resolved_name): if not self._is_service_ready(self.grasp_service):
return False return False
return True return True
@@ -119,7 +136,7 @@ class FrankaGripperInterface:
def is_done(self): def is_done(self):
""" Check if the gripper is done moving or grasping """ """ Check if the gripper is done moving or grasping """
if not self.is_busy(): if not self.is_busy():
rospy.logwarn("Gripper is not moving or grasping") self.node.get_logger().warn("Gripper is not moving or grasping")
return False return False
else: else:
if self.result_queue.empty(): if self.result_queue.empty():
@@ -149,34 +166,38 @@ class FrankaGripperInterface:
raise Exception("Gripper is not enabled") raise Exception("Gripper is not enabled")
if not self._moving and not self._grasping: if not self._moving and not self._grasping:
raise Exception("Gripper is not moving or grasping") raise Exception("Gripper is not moving or grasping")
if not self._moving or self._grasping:
raise Exception("Gripper is not moving or grasping")
while self._moving or self._grasping: while self._moving or self._grasping:
rospy.sleep(0.1) self.spin_handler()
time.sleep(0.1)
if not self.result_queue.empty(): if not self.result_queue.empty():
response = self.result_queue.get() response = self.result_queue.get()
if isinstance(response, MoveResponse): if isinstance(response, Move_Response):
self._moving = False self._moving = False
elif isinstance(response, GraspResponse): elif isinstance(response, Grasp_Response):
self._grasping = False self._grasping = False
else: else:
raise Exception("Invalid response type") raise Exception("Invalid response type")
break break
return response.success return response.success
def _move(self, width, speed): def _move(self, width, speed):
self._moving = True self._moving = True
request = MoveRequest() request = Move_Request()
request.width = width request.width = width
request.speed = speed request.speed = speed
response = self.move_service(request) response = self.move_service.call(request)
self.result_queue.put(response) self.result_queue.put(response)
def _grasp(self, width, force, speed, epsilon_inner, epsilon_outer): def _grasp(self, width, force, speed, epsilon_inner, epsilon_outer):
self._grasping = True self._grasping = True
request = GraspRequest() request = Grasp_Request()
request.width = width request.width = width
request.force = force request.force = force
request.speed = speed request.speed = speed
request.epsilon_inner = epsilon_inner request.epsilon_inner = epsilon_inner
request.epsilon_outer = epsilon_outer request.epsilon_outer = epsilon_outer
response = self.grasp_service(request) response = self.grasp_service.call(request)
self.result_queue.put(response) self.result_queue.put(response)

View File

@@ -1,48 +1,61 @@
import rospy import threading
from sas_common import rclcpp_init, rclcpp_Node, rclcpp_spin_some, rclcpp_shutdown
import rclpy
from sas_robot_driver_franka import FrankaGripperInterface from sas_robot_driver_franka import FrankaGripperInterface
import time
def main_loop(): def main_loop(node):
rate = rospy.Rate(10) # 10 Hz
iteration_ = 0 iteration_ = 0
node_name = node.get_name()
hand1 = FrankaGripperInterface("/franka_hand_1") hand1 = FrankaGripperInterface(node, "/franka_hand_1")
logger = rclpy.node.get_logger(node_name)
while not hand1.is_enabled(): while not hand1.is_enabled():
rospy.loginfo("Waiting for gripper to be enabled...") logger.info("Waiting for gripper to be enabled...")
rate.sleep() rclcpp_spin_some(node)
rospy.loginfo("Gripper enabled!") time.sleep(0.1)
rclpy.node.get_logger(node_name).info("Gripper enabled!")
rate = rospy.Rate(2) # 0.5 Hz def spin_all(node_):
while rclpy.ok():
rclcpp_spin_some(node_)
rclpy.spin_once(node_, timeout_sec=0.1)
time.sleep(0.1)
while not rospy.is_shutdown(): thread = threading.Thread(target=spin_all, args=(node, ), daemon=True)
rospy.loginfo("Main loop running...") thread.start()
rate = node.create_rate(2)
while rclpy.ok():
logger.info("Main loop running...")
# Get the temperature of the gripper # Get the temperature of the gripper
temperature = hand1.get_temperature() temperature = hand1.get_temperature()
rospy.loginfo(f"Temperature: {temperature}") logger.info(f"Temperature: {temperature}")
max_width = hand1.get_max_width() max_width = hand1.get_max_width()
rospy.loginfo(f"Max width: {max_width}") logger.info(f"Max width: {max_width}")
width = hand1.get_width() width = hand1.get_width()
rospy.loginfo(f"Width: {width}") logger.info(f"Width: {width}")
is_grasped = hand1.is_grasped() is_grasped = hand1.is_grasped()
rospy.loginfo(f"Is grasped: {is_grasped}") logger.info(f"Is grasped: {is_grasped}")
is_moving = hand1.is_moving() is_moving = hand1.is_moving()
rospy.loginfo(f"Is moving: {is_moving}") logger.info(f"Is moving: {is_moving}")
is_grasping = hand1.is_grasping() is_grasping = hand1.is_grasping()
rospy.loginfo(f"Is grasping: {is_grasping}") logger.info(f"Is grasping: {is_grasping}")
rospy.logwarn("calling move(0.01)") logger.warn("calling move(0.01)")
if not hand1.is_busy(): if not hand1.is_busy():
hand1.grasp(0.01) hand1.grasp(0.01)
else: else:
rospy.logwarn("Gripper is busy. Waiting...") logger.warn("Gripper is busy. Waiting...")
result_ready = hand1.is_done() result_ready = hand1.is_done()
if not result_ready: if not result_ready:
rospy.loginfo("Waiting for gripper to finish moving...") logger.info("Waiting for gripper to finish moving...")
else: else:
result = hand1.get_result() result = hand1.get_result()
rospy.loginfo(f"Result: {result}") logger.info(f"Result: {result}")
# Check if there is a response in the queue # Check if there is a response in the queue
@@ -50,7 +63,12 @@ def main_loop():
iteration_ += 1 iteration_ += 1
rate.sleep() rate.sleep()
rclpy.shutdown()
thread.join()
if __name__ == "__main__": if __name__ == "__main__":
rospy.init_node("example_gripper_control_node") rclpy.init()
main_loop() node_name_ = "example_gripper_control_node"
NODE = rclpy.create_node(node_name_)
main_loop(NODE)

View File

@@ -1,5 +1,5 @@
import rospy import rospy
from sas_robot_driver_franka import RobotDynamicsProvider from sas_robot_driver_franka import RobotDynamicsServer
import dqrobotics as dql import dqrobotics as dql
import numpy as np import numpy as np

View File

@@ -1,12 +0,0 @@
# ! DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD
from distutils.core import setup
from catkin_pkg.python_setup import generate_distutils_setup
# fetch values from package.xml
setup_args = generate_distutils_setup(
packages=['sas_robot_driver_franka'],
package_dir={'': 'src'},
)
setup(**setup_args)

View File

@@ -1,253 +1,247 @@
#include "sas_robot_driver_coppelia.h" #include <sas_robot_driver_franka/coppelia/sas_robot_driver_coppelia.hpp>
namespace sas namespace qros
{ {
RobotDriverCoppelia::~RobotDriverCoppelia() {
deinitialize();
disconnect();
}
RobotDriverCoppelia::RobotDriverCoppelia(const RobotDriverCoppeliaConfiguration &configuration, std::atomic_bool *break_loops): RobotDriverCoppelia::RobotDriverCoppelia(const std::shared_ptr<Node> &node_sptr, const RobotDriverCoppeliaConfiguration &configuration, std::atomic_bool *break_loops):
RobotDriver(break_loops),
configuration_(configuration), configuration_(configuration),
robot_mode_(configuration.robot_mode), node_sptr_(node_sptr),
jointnames_(configuration.jointnames), clock_(configuration.thread_sampling_time_sec),
mirror_mode_(configuration.mirror_mode), break_loops_(break_loops),
dim_configuration_space_(configuration.jointnames.size()), robot_mode_(ControlMode::Position),
real_robot_topic_prefix_(configuration.real_robot_topic_prefix) vi_(std::make_shared<DQ_VrepInterface>())
{ {
vi_ = std::make_shared<DQ_VrepInterface>(); // should initialize robot driver interface to real robot
desired_joint_velocities_ = VectorXd::Zero(dim_configuration_space_); DQ_SerialManipulatorDH smdh = DQ_JsonReader::get_from_json<DQ_SerialManipulatorDH>(configuration_.robot_parameter_file_path);
auto nodehandle = ros::NodeHandle(); joint_limits_ = {smdh.get_lower_q_limit(),smdh.get_upper_q_limit()};
std::cout<<"RobotDriverCoppelia::Rostopic: "<<"/"+real_robot_topic_prefix_<<std::endl; if(configuration_.using_real_robot)
franka1_ros_ = std::make_shared<sas::RobotDriverInterface>(nodehandle, "/"+real_robot_topic_prefix_);
}
VectorXd RobotDriverCoppelia::get_joint_positions()
{ {
return current_joint_positions_; RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Using real robot, Instantiating robot interface to real driver at ["+configuration_.robot_topic_prefix+"].");
} real_robot_interface_ = std::make_shared<sas::RobotDriverClient>(node_sptr_, configuration_.robot_topic_prefix);
void RobotDriverCoppelia::set_target_joint_positions(const VectorXd &desired_joint_positions_rad)
{
desired_joint_positions_ = desired_joint_positions_rad;
}
VectorXd RobotDriverCoppelia::get_joint_velocities()
{
return current_joint_velocities_;
}
void RobotDriverCoppelia::set_target_joint_velocities(const VectorXd &desired_joint_velocities)
{
desired_joint_velocities_ = desired_joint_velocities;
}
VectorXd RobotDriverCoppelia::get_joint_forces()
{
return current_joint_forces_;
}
RobotDriverCoppelia::~RobotDriverCoppelia()=default;
void RobotDriverCoppelia::connect()
{
vi_->connect(configuration_.ip, configuration_.port, 500, 10);
vi_->set_joint_target_velocities(jointnames_, VectorXd::Zero(dim_configuration_space_));
std::cout<<"RobotDriverCoppelia::Connecting..."<<std::endl;
}
void RobotDriverCoppelia::disconnect()
{
vi_->disconnect();
if (joint_velocity_control_mode_thread_.joinable())
{
joint_velocity_control_mode_thread_.join();
}
if (joint_velocity_control_mirror_mode_thread_.joinable())
{
joint_velocity_control_mirror_mode_thread_.join();
}
std::cout<<"RobotDriverCoppelia::Disconnected."<<std::endl;
}
void RobotDriverCoppelia::initialize()
{
vi_->start_simulation();
if (mirror_mode_ == false)
{
_start_joint_velocity_control_thread();
}else{ }else{
_start_joint_velocity_control_mirror_thread(); RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Using simulation robot, simulation mode is set to "+ configuration_.robot_mode);
robot_provider_ = std::make_shared<sas::RobotDriverServer>(node_sptr_, configuration_.robot_topic_prefix);
std::string _mode_upper = configuration_.robot_mode;
std::transform(_mode_upper.begin(), _mode_upper.end(), _mode_upper.begin(), ::toupper);
if(_mode_upper == "POSITIONCONTROL"){
robot_mode_ = ControlMode::Position;
}else if(_mode_upper == "VELOCITYCONTROL"){
robot_mode_ = ControlMode::Velocity;
}else{
throw std::invalid_argument("[" + std::string(node_sptr_->get_name()) + "]::Robot mode must be either 'position' or 'velocity'");
} }
std::cout<<"RobotDriverCoppelia::Velocity loop running..."<<std::endl;
} }
void RobotDriverCoppelia::deinitialize() }
void RobotDriverCoppelia::_update_vrep_position(const VectorXd &joint_positions, const bool& force_update) const{
if(configuration_.vrep_dynamically_enabled){
if(force_update){
vi_->set_joint_positions(configuration_.vrep_joint_names, joint_positions);
}
vi_->set_joint_target_positions(configuration_.vrep_joint_names, joint_positions);
}else{
vi_->set_joint_positions(configuration_.vrep_joint_names, joint_positions);
}
}
void RobotDriverCoppelia::_update_vrep_velocity(const VectorXd & joint_velocity) const{
if(!configuration_.vrep_dynamically_enabled){
throw std::runtime_error("[RobotDriverCoppelia]::[_update_vrep_velocity]::Vrep is not dynamically enabled");
}
vi_->set_joint_target_velocities(configuration_.vrep_joint_names, joint_velocity);
}
void RobotDriverCoppelia::_start_control_loop(){
clock_.init();
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Starting control loop...");
while(!_should_shutdown()){
clock_.update_and_sleep();
rclcpp::spin_some(node_sptr_);
if(!rclcpp::ok()){break_loops_->store(true);}
if(configuration_.using_real_robot){
// real_robot_interface_
auto joint_position = real_robot_interface_->get_joint_positions();
_update_vrep_position(joint_position);
}else{
// robot_provider_
VectorXd target_joint_positions;
auto current_joint_positions = vi_->get_joint_positions(configuration_.vrep_joint_names);
VectorXd current_joint_velocity;
if(robot_provider_->is_enabled()) {
if(robot_mode_ == ControlMode::Velocity)
{ {
vi_->set_joint_target_velocities(jointnames_, VectorXd::Zero(dim_configuration_space_)); if(robot_provider_->is_enabled(sas::RobotDriver::Functionality::VelocityControl)) {
vi_->stop_simulation(); simulated_joint_velocities_ = robot_provider_->get_target_joint_velocities();
finish_motion(); current_joint_velocity = simulated_joint_velocities_;
std::cout<<"RobotDriverCoppelia::Deinitialized."<<std::endl; // try{_update_vrep_velocity(simulated_joint_velocities_);}catch (...){}
}
else{
RCLCPP_DEBUG_STREAM(node_sptr_->get_logger(), "::Velocity control is not enabled.");
}
target_joint_positions = simulated_joint_positions_;
}else{
target_joint_positions = robot_provider_->get_target_joint_positions();
}
}else {
target_joint_positions = current_joint_positions;
}
_update_vrep_position(target_joint_positions);
robot_provider_->send_joint_states(current_joint_positions, current_joint_velocity, VectorXd());
robot_provider_->send_joint_limits(joint_limits_);
}
} }
void RobotDriverCoppelia::_update_robot_state(const VectorXd &q, const VectorXd &q_dot, const VectorXd &forces)
{
current_joint_positions_ = q;
current_joint_velocities_ = q_dot;
current_joint_forces_ = forces;
} }
void RobotDriverCoppelia::finish_motion() int RobotDriverCoppelia::start_control_loop(){
{
for (int i=0;i<1000;i++)
{
set_target_joint_positions(current_joint_positions_);
set_target_joint_velocities(VectorXd::Zero(dim_configuration_space_));
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
finish_motion_ = true;
}
void RobotDriverCoppelia::_start_joint_velocity_control_mode()
{
try{ try{
finish_motion_ = false; RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Waiting to connect with coppelia...");
VectorXd q = vi_->get_joint_positions(jointnames_); connect();
VectorXd q_dot = vi_->get_joint_velocities(jointnames_); RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Connected to coppelia.");
VectorXd forces = vi_->get_joint_torques(jointnames_); RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Initializing...");
_update_robot_state(q, q_dot, forces); initialize();
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::initialized.");
desired_joint_positions_ = q; _start_control_loop();
while(true)
{
VectorXd q = vi_->get_joint_positions(jointnames_);
VectorXd q_dot = vi_->get_joint_velocities(jointnames_);
VectorXd forces = vi_->get_joint_torques(jointnames_);
_update_robot_state(q, q_dot, forces);
if (robot_mode_ == std::string("VelocityControl"))
{
vi_->set_joint_target_velocities(jointnames_, desired_joint_velocities_);
}
else if (robot_mode_ == std::string("PositionControl"))
{
vi_->set_joint_target_positions(jointnames_, desired_joint_positions_);
}
if (finish_motion_) {
finish_motion_ = false;
return;
}
}
} }
catch(const std::exception& e) catch(const std::exception& e)
{ {
std::cout<<"RobotDriverCoppelia::sas_robot_coppelia_driver::_start_joint_velocity_control_mode(). Error or exception caught " << e.what()<<std::endl; RCLCPP_WARN_STREAM(node_sptr_->get_logger(), "::Error or exception caught::" << e.what());
} }
catch(...) catch(...)
{ {
std::cout<<"RobotDriverCoppelia::sas_robot_coppelia_driver::_start_joint_velocity_control_mode(). Error or exception caught " <<std::endl; RCLCPP_WARN_STREAM(node_sptr_->get_logger(), "::Unexpected error or exception caught");
}
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Deinitializing...");
deinitialize();
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::deinitialized.");
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Disconnecting from coppelia...");
disconnect();
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Disconnected from coppelia.");
return 0;
} }
void RobotDriverCoppelia::connect(){
auto ret = vi_->connect(configuration_.vrep_ip, configuration_.vrep_port, 100, 10);
if(!ret){
throw std::runtime_error("[RobotDriverCoppelia]::connect::Could not connect to Vrep");
}
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::connect::Connected to Vrep");
}
void RobotDriverCoppelia::disconnect(){
vi_->disconnect_all();
} }
void RobotDriverCoppelia::_start_joint_velocity_control_thread() void RobotDriverCoppelia::initialize(){
if(configuration_.using_real_robot)
{ {
finish_motion_ = false; RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::initialize::Waiting for real robot interface to initialize...");
if (joint_velocity_control_mode_thread_.joinable()) rclcpp::spin_some(node_sptr_);
{ int count = 0;
joint_velocity_control_mode_thread_.join(); while (!real_robot_interface_->is_enabled(sas::RobotDriver::Functionality::PositionControl)) {
rclcpp::spin_some(node_sptr_);
// std::cout<<"Waiting for real robot interface to initialize..."<<std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
rclcpp::spin_some(node_sptr_);
count++;
if(count > REAL_ROBOT_INTERFACE_INIT_TIMEOUT_COUNT){
RCLCPP_ERROR_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::initialize::Real robot interface not initialized. Exiting on TIMEOUT...");
throw std::runtime_error("[" + std::string(node_sptr_->get_name()) +"]::[RobotDriverCoppelia]::initialize::Real robot interface not initialized.");
} }
if (joint_velocity_control_mirror_mode_thread_.joinable()) if(!rclcpp::ok()) {
{ RCLCPP_WARN_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::initialize::ROS shutdown received. Exiting...");
joint_velocity_control_mirror_mode_thread_.join(); throw std::runtime_error("[" + std::string(node_sptr_->get_name()) +"]::[RobotDriverCoppelia]::initialize::ROS shutdown received, not OK.");
} }
joint_velocity_control_mode_thread_ = std::thread(&RobotDriverCoppelia::_start_joint_velocity_control_mode, this); }
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::initialize::Real robot interface initialized.");
joint_limits_ = real_robot_interface_->get_joint_limits();
_update_vrep_position(real_robot_interface_->get_joint_positions(), true);
}else{
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::initialize::Simulation mode.");
// initialization information for robot driver provider
/**
* TODO: check for making sure real robot is not actually connected
*/
auto current_joint_positions = vi_->get_joint_positions(configuration_.vrep_joint_names);
VectorXd current_joint_velocity;
if(robot_mode_ == ControlMode::Velocity)
{current_joint_velocity = VectorXd::Zero(current_joint_positions.size());}
robot_provider_->send_joint_states(current_joint_positions, current_joint_velocity, VectorXd());
robot_provider_->send_joint_limits(joint_limits_);
// start velocity control simulation thread if needed
if(robot_mode_ == ControlMode::Velocity)
{
simulated_joint_positions_ = current_joint_positions;
simulated_joint_velocities_ = current_joint_velocity;
start_simulation_thread();
}
}
}
void RobotDriverCoppelia::deinitialize(){
// nothing to do
} }
void RobotDriverCoppelia::_start_joint_velocity_control_mirror_thread() void RobotDriverCoppelia::start_simulation_thread(){ // thread entry point
{ if(simulation_thread_started_){
finish_motion_ = false; throw std::runtime_error("[RobotDriverCoppelia]::start_simulation_thread::Simulation thread already started");
if (joint_velocity_control_mode_thread_.joinable())
{
joint_velocity_control_mode_thread_.join();
} }
if (joint_velocity_control_mirror_mode_thread_.joinable()) if(velocity_control_simulation_thread_.joinable()){
{ velocity_control_simulation_thread_.join();
joint_velocity_control_mirror_mode_thread_.join();
}
joint_velocity_control_mirror_mode_thread_ = std::thread(&RobotDriverCoppelia::_start_joint_velocity_control_mirror_mode, this);
} }
void RobotDriverCoppelia::_start_joint_velocity_control_mirror_mode() velocity_control_simulation_thread_ = std::thread(&RobotDriverCoppelia::_velocity_control_simulation_thread_main, this);
{ }
void RobotDriverCoppelia::_velocity_control_simulation_thread_main(){
/**
* This thread should not access vrep
*/
simulation_thread_started_ = true;
try{ try{
finish_motion_ = false; RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::RobotDriverCoppelia]::[_velocity_control_simulation_thread_main]::Simulation thread started.");
std::cout<<"RobotDriverCoppelia::Waiting for real robot topics..."<<std::endl; sas::Clock clock = sas::Clock(VIRTUAL_ROBOT_SIMULATION_SAMPLING_TIME_SEC);
VectorXd q; double tau = VIRTUAL_ROBOT_SIMULATION_SAMPLING_TIME_SEC;
while (ros::ok()) { auto current_joint_positions = simulated_joint_positions_;
if (franka1_ros_->is_enabled()) clock.init();
{ while (!(*break_loops_) && rclcpp::ok()) {
q = franka1_ros_->get_joint_positions();
break;
}
ros::spinOnce();
}
std::cout<<"RobotDriverCoppelia::Done!"<<std::endl;
VectorXd q_vrep = vi_->get_joint_positions(jointnames_); current_joint_positions += tau * simulated_joint_velocities_; // no dynamic model
VectorXd q_dot_vrep = vi_->get_joint_velocities(jointnames_); // cap joint limit
VectorXd forces_vrep = vi_->get_joint_torques(jointnames_); auto q_min = std::get<0>(joint_limits_);
_update_robot_state(q_vrep, q_dot_vrep, forces_vrep); auto q_max = std::get<1>(joint_limits_);
for (int i = 0; i < current_joint_positions.size(); i++) {
desired_joint_positions_ = q_vrep; if (current_joint_positions(i) < q_min(i)) {
current_joint_positions(i) = q_min(i);
while(ros::ok())
{
q = franka1_ros_->get_joint_positions();
if (q.size() == dim_configuration_space_)
{
VectorXd q_vrep = vi_->get_joint_positions(jointnames_);
VectorXd q_dot_vrep = vi_->get_joint_velocities(jointnames_);
VectorXd forces_vrep = vi_->get_joint_torques(jointnames_);
_update_robot_state(q_vrep, q_dot_vrep, forces_vrep);
if (robot_mode_ == std::string("VelocityControl"))
{
vi_->set_joint_target_velocities(jointnames_, gain_*(q-q_vrep));
} }
else if (robot_mode_ == std::string("PositionControl")) if (current_joint_positions(i) > q_max(i)) {
{ current_joint_positions(i) = q_max(i);
vi_->set_joint_target_positions(jointnames_, q);
}
if (finish_motion_) {
finish_motion_ = false;
return;
} }
} }
simulated_joint_positions_ = current_joint_positions;
clock.update_and_sleep();
} }
}catch(std::exception &e){
RCLCPP_ERROR_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::[_velocity_control_simulation_thread_main]::Exception::" << e.what());
simulation_thread_started_ = false;
}catch(...){
RCLCPP_ERROR_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::[_velocity_control_simulation_thread_main]::Exception::Unknown");
simulation_thread_started_ = false;
} }
catch(const std::exception& e) break_loops_->store(true);
{
std::cout<<"RobotDriverCoppelia::sas_robot_coppelia_driver::_start_joint_velocity_control_mirror_mode(). Error or exception caught " << e.what()<<std::endl;
}
catch(...)
{
std::cout<<"RobotDriverCoppelia::sas_robot_coppelia_driver::_start_joint_velocity_control_mirror_mode(). Error or exception caught " <<std::endl;
}
} }
} // sas namespace } // sas namespace

View File

@@ -1,134 +0,0 @@
/*
# Copyright (c) 2023 Juan Jose Quiroz Omana
#
# This file is part of sas_robot_driver_franka.
#
# sas_robot_driver_franka is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sas_robot_driver_franka is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with sas_robot_driver. If not, see <https://www.gnu.org/licenses/>.
#
# ################################################################
#
# Author: Juan Jose Quiroz Omana, email: juanjqogm@gmail.com
#
# ################################################################
#
# Contributors:
# 1. Juan Jose Quiroz Omana (juanjqogm@gmail.com)
# - Adapted from sas_robot_driver_denso.cpp
# (https://github.com/SmartArmStack/sas_robot_driver_denso/blob/master/src/sas_robot_driver_denso.cpp)
#
# ################################################################
*/
#pragma once
#include <exception>
#include <tuple>
#include <atomic>
#include <vector>
#include <memory>
#include <dqrobotics/DQ.h>
#include <sas_robot_driver/sas_robot_driver.h>
#include <dqrobotics/interfaces/vrep/DQ_VrepRobot.h>
#include <thread>
#include <sas_robot_driver/sas_robot_driver_interface.h>
using namespace DQ_robotics;
using namespace Eigen;
namespace sas
{
struct RobotDriverCoppeliaConfiguration
{
int thread_sampling_time_nsec;
int port;
std::string ip;
std::vector<std::string> jointnames;
std::string robot_mode;
bool mirror_mode;
std::string real_robot_topic_prefix;
};
class RobotDriverCoppelia: public RobotDriver
{
private:
RobotDriverCoppeliaConfiguration configuration_;
std::string robot_mode_ = std::string("VelocityControl"); // PositionControl
bool mirror_mode_ = false;
double gain_ = 3.0;
std::string real_robot_topic_prefix_;
VectorXd current_joint_positions_;
VectorXd current_joint_velocities_;
VectorXd current_joint_forces_;
VectorXd desired_joint_velocities_;
VectorXd desired_joint_positions_;
std::atomic<bool> finish_motion_;
int dim_configuration_space_;
void _update_robot_state(const VectorXd& q, const VectorXd& q_dot, const VectorXd& forces);
void finish_motion();
void _start_joint_velocity_control_mode();
std::thread joint_velocity_control_mode_thread_;
void _start_joint_velocity_control_thread();
void _start_joint_velocity_control_mirror_mode();
std::thread joint_velocity_control_mirror_mode_thread_;
void _start_joint_velocity_control_mirror_thread();
std::shared_ptr<sas::RobotDriverInterface> franka1_ros_;
protected:
std::shared_ptr<DQ_VrepInterface> vi_;
std::vector<std::string> jointnames_;
public:
RobotDriverCoppelia(const RobotDriverCoppelia&)=delete;
RobotDriverCoppelia()=delete;
~RobotDriverCoppelia();
RobotDriverCoppelia(const RobotDriverCoppeliaConfiguration& configuration, std::atomic_bool* break_loops);
VectorXd get_joint_positions() override;
void set_target_joint_positions(const VectorXd& desired_joint_positions_rad) override;
VectorXd get_joint_velocities() override;
void set_target_joint_velocities(const VectorXd& desired_joint_velocities) override;
VectorXd get_joint_forces() override;
void connect() override;
void disconnect() override;
void initialize() override;
void deinitialize() override;
};
}

View File

@@ -28,7 +28,7 @@
# #
# ################################################################ # ################################################################
*/ */
#include "generator/custom_motion_generation.h" #include <sas_robot_driver_franka/generator/custom_motion_generation.h>
/** /**
* @brief CustomMotionGeneration::CustomMotionGeneration * @brief CustomMotionGeneration::CustomMotionGeneration

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2017 Franka Emika GmbH // Copyright (c) 2017 Franka Emika GmbH
// Use of this source code is governed by the Apache-2.0 license, see LICENSE // Use of this source code is governed by the Apache-2.0 license, see LICENSE
#include "generator/motion_generator.h" #include <sas_robot_driver_franka/generator/motion_generator.h>
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cmath> #include <cmath>

View File

@@ -1,4 +1,4 @@
#include "generator/quadratic_program_motion_generator.h" #include <sas_robot_driver_franka/generator/quadratic_program_motion_generator.h>
QuadraticProgramMotionGenerator::QuadraticProgramMotionGenerator(const double &speed_factor, QuadraticProgramMotionGenerator::QuadraticProgramMotionGenerator(const double &speed_factor,

View File

@@ -27,10 +27,13 @@
# #
# ################################################################ # ################################################################
*/ */
#include "hand/qros_effector_driver_franka_hand.h" #include <sas_robot_driver_franka/interfaces/qros_effector_driver_franka_hand.hpp>
#include <franka/exception.h> #include <franka/exception.h>
using namespace std::placeholders;
using namespace sas_robot_driver_franka_interfaces;
namespace qros namespace qros
{ {
@@ -48,19 +51,19 @@ namespace qros
EffectorDriverFrankaHand::EffectorDriverFrankaHand( EffectorDriverFrankaHand::EffectorDriverFrankaHand(
const std::string& driver_node_prefix, const std::string& driver_node_prefix,
const EffectorDriverFrankaHandConfiguration& configuration, const EffectorDriverFrankaHandConfiguration& configuration,
ros::NodeHandle& node_handel, std::shared_ptr<Node> node,
std::atomic_bool* break_loops): std::atomic_bool* break_loops):
driver_node_prefix_(driver_node_prefix), driver_node_prefix_(driver_node_prefix),
configuration_(configuration), configuration_(configuration),
node_handel_(node_handel), node_(node),
break_loops_(break_loops) break_loops_(break_loops)
{ {
gripper_sptr_ = nullptr; gripper_sptr_ = nullptr;
grasp_server_ = node_handel_.advertiseService(driver_node_prefix_ + "/grasp", grasp_srv_ = node->create_service<srv::Grasp>(driver_node_prefix_ + "/grasp",
&EffectorDriverFrankaHand::_grasp_srv_callback, this); std::bind(&EffectorDriverFrankaHand::_grasp_srv_callback, this, _1, _2));
move_server_ = node_handel_.advertiseService(driver_node_prefix_ + "/move", move_srv_ = node->create_service<srv::Move>(driver_node_prefix_ + "/move",
&EffectorDriverFrankaHand::_move_srv_callback, this); std::bind(&EffectorDriverFrankaHand::_move_srv_callback, this, _1, _2));
gripper_status_publisher_ = node_handel_.advertise<sas_robot_driver_franka::GripperState>( gripper_status_publisher_ = node->create_publisher<msg::GripperState>(
driver_node_prefix_ + "/gripper_status", 1); driver_node_prefix_ + "/gripper_status", 1);
} }
@@ -77,54 +80,47 @@ namespace qros
void EffectorDriverFrankaHand::start_control_loop() void EffectorDriverFrankaHand::start_control_loop()
{ {
sas::Clock clock = sas::Clock(configuration_.thread_sampeling_time_ns); sas::Clock clock = sas::Clock(configuration_.thread_sampeling_time_s);
clock.init(); clock.init();
ROS_INFO_STREAM( RCLCPP_INFO_STREAM(node_->get_logger(),
"["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::start_control_loop::Starting control loop."); "["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::start_control_loop::Starting control loop.");
while (!(*break_loops_)) while (!(*break_loops_))
{ {
if (!_is_connected()) throw std::runtime_error( if (!_is_connected()) throw std::runtime_error("[" + std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::start_control_loop::Robot is not connected.");
"[" + ros::this_node::getName() +
"]::[EffectorDriverFrankaHand]::start_control_loop::Robot is not connected.");
if (!status_loop_running_) if (!status_loop_running_)
{ {
ROS_WARN_STREAM( RCLCPP_WARN_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_is_connected::Status loop is not running.");
"["+ ros::this_node::getName()+
"]::[EffectorDriverFrankaHand]::_is_connected::Status loop is not running.");
break_loops_->store(true); break_loops_->store(true);
break; break;
} }
clock.update_and_sleep(); clock.update_and_sleep();
ros::spinOnce(); spin_some(node_);
} }
ROS_INFO_STREAM( RCLCPP_INFO_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::start_control_loop::Exiting control loop.");
"["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::start_control_loop::Exiting control loop.");
} }
void EffectorDriverFrankaHand::connect() void EffectorDriverFrankaHand::connect()
{ {
#ifdef IN_TESTING #ifdef IN_TESTING
ROS_WARN_STREAM( RCLCPP_WARN_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::connect::In testing mode. to DUMMY");
"["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::connect::In testing mode. to DUMMY");
return; return;
#endif #endif
gripper_sptr_ = std::make_shared<franka::Gripper>(configuration_.robot_ip); gripper_sptr_ = std::make_shared<franka::Gripper>(configuration_.robot_ip);
if (!_is_connected()) throw std::runtime_error( if (!_is_connected()) throw std::runtime_error(
"[" + ros::this_node::getName() + "[" + std::string(node_->get_name())+
"]::[EffectorDriverFrankaHand]::connect::Could not connect to the robot."); "]::[EffectorDriverFrankaHand]::connect::Could not connect to the robot.");
} }
void EffectorDriverFrankaHand::disconnect() noexcept void EffectorDriverFrankaHand::disconnect() noexcept
{ {
#ifdef IN_TESTING #ifdef IN_TESTING
ROS_WARN_STREAM( RCLCPP_WARN_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::disconnect::In testing mode. from DUMMY");
"["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::disconnect::In testing mode. from DUMMY");
return; return;
#endif #endif
ROS_WARN_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::disconnecting..."); RCLCPP_WARN_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::disconnecting...");
gripper_sptr_->~Gripper(); gripper_sptr_->~Gripper();
gripper_sptr_ = nullptr; gripper_sptr_ = nullptr;
} }
@@ -135,26 +131,23 @@ namespace qros
void EffectorDriverFrankaHand::gripper_homing() void EffectorDriverFrankaHand::gripper_homing()
{ {
#ifdef IN_TESTING #ifdef IN_TESTING
ROS_WARN_STREAM( RCLCPP_WARN_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::gripper_homing::In testing mode.");
"["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::gripper_homing::In testing mode.");
return; return;
#endif #endif
if (!_is_connected()) throw std::runtime_error( if (!_is_connected()) throw std::runtime_error(
"[" + ros::this_node::getName() + "]::[EffectorDriverFrankaHand]::gripper_homing::Robot is not connected."); "[" + std::string(node_->get_name())+ "]::[EffectorDriverFrankaHand]::gripper_homing::Robot is not connected.");
auto ret = gripper_sptr_->homing(); auto ret = gripper_sptr_->homing();
if (!ret) if (!ret)
{ {
throw std::runtime_error( throw std::runtime_error("[" + std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::gripper_homing::Failed to home the gripper.");
"[" + ros::this_node::getName() +
"]::[EffectorDriverFrankaHand]::gripper_homing::Failed to home the gripper.");
} }
ROS_INFO_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::gripper_homing::Gripper homed."); RCLCPP_INFO_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::gripper_homing::Gripper homed.");
} }
void EffectorDriverFrankaHand::initialize() void EffectorDriverFrankaHand::initialize()
{ {
if (!_is_connected()) throw std::runtime_error( if (!_is_connected()) throw std::runtime_error(
"[" + ros::this_node::getName() + "]::[EffectorDriverFrankaHand]::initialize::Robot is not connected."); "[" + std::string(node_->get_name())+ "]::[EffectorDriverFrankaHand]::initialize::Robot is not connected.");
gripper_homing(); gripper_homing();
// start gripper status loop // start gripper status loop
status_loop_thread_ = std::thread(&EffectorDriverFrankaHand::_gripper_status_loop, this); status_loop_thread_ = std::thread(&EffectorDriverFrankaHand::_gripper_status_loop, this);
@@ -163,7 +156,7 @@ namespace qros
void EffectorDriverFrankaHand::deinitialize() void EffectorDriverFrankaHand::deinitialize()
{ {
#ifdef IN_TESTING #ifdef IN_TESTING
ROS_WARN_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::deinitialize::In testing mode."); RCLCPP_WARN_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::deinitialize::In testing mode.");
return; return;
#endif #endif
if (_is_connected()) if (_is_connected())
@@ -177,20 +170,19 @@ namespace qros
} }
bool EffectorDriverFrankaHand::_grasp_srv_callback(sas_robot_driver_franka::Grasp::Request& req, bool EffectorDriverFrankaHand::_grasp_srv_callback(const std::shared_ptr<srv::Grasp::Request> req, std::shared_ptr<srv::Grasp::Response> res)
sas_robot_driver_franka::Grasp::Response& res)
{ {
ROS_DEBUG_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_grasp_srv_callback::Grasping..."); RCLCPP_DEBUG_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_grasp_srv_callback::Grasping...");
auto force = req.force; auto force = req->force;
auto speed = req.speed; auto speed = req->speed;
auto epsilon_inner = req.epsilon_inner; auto epsilon_inner = req->epsilon_inner;
auto epsilon_outer = req.epsilon_outer; auto epsilon_outer = req->epsilon_outer;
if (force <= 0.0) force = configuration_.default_force; if (force <= 0.0) force = configuration_.default_force;
if (speed <= 0.0) speed = configuration_.default_speed; if (speed <= 0.0) speed = configuration_.default_speed;
if (epsilon_inner <= 0.0) epsilon_inner = configuration_.default_epsilon_inner; if (epsilon_inner <= 0.0) epsilon_inner = configuration_.default_epsilon_inner;
if (epsilon_outer <= 0.0) epsilon_outer = configuration_.default_epsilon_outer; if (epsilon_outer <= 0.0) epsilon_outer = configuration_.default_epsilon_outer;
ROS_DEBUG_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_grasp_srv_callback::Width: " + std::to_string(req.width)); RCLCPP_DEBUG_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_grasp_srv_callback::Width: " + std::to_string(req->width));
ROS_DEBUG_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_grasp_srv_callback::force: " + std::to_string(force) + " speed: " + std::to_string(speed)); RCLCPP_DEBUG_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_grasp_srv_callback::force: " + std::to_string(force) + " speed: " + std::to_string(speed));
bool ret = false; bool ret = false;
bool function_ret = true; bool function_ret = true;
gripper_in_use_.lock(); gripper_in_use_.lock();
@@ -200,30 +192,29 @@ namespace qros
#else #else
try try
{ {
ret = gripper_sptr_->grasp(req.width, speed, force, epsilon_inner, epsilon_outer); ret = gripper_sptr_->grasp(req->width, speed, force, epsilon_inner, epsilon_outer);
}catch(franka::CommandException& e) }catch(franka::CommandException& e)
{ {
ROS_ERROR_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_grasp_srv_callback::CommandException::" + e.what()); RCLCPP_ERROR_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_grasp_srv_callback::CommandException::" + e.what());
function_ret = false; function_ret = false;
}catch(franka::NetworkException& e) }catch(franka::NetworkException& e)
{ {
ROS_ERROR_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_grasp_srv_callback::NetworkException::" + e.what()); RCLCPP_ERROR_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_grasp_srv_callback::NetworkException::" + e.what());
function_ret = false; function_ret = false;
} }
#endif #endif
gripper_in_use_.unlock(); gripper_in_use_.unlock();
res.success = ret; res->set__success(ret);
return function_ret; return function_ret;
} }
bool EffectorDriverFrankaHand::_move_srv_callback(sas_robot_driver_franka::Move::Request& req, bool EffectorDriverFrankaHand::_move_srv_callback(const std::shared_ptr<srv::Move::Request> req, std::shared_ptr<srv::Move::Response> res)
sas_robot_driver_franka::Move::Response& res)
{ {
ROS_DEBUG_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_move_srv_callback::Moving..."); RCLCPP_DEBUG_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_move_srv_callback::Moving...");
auto speed = req.speed; auto speed = req->speed;
if (speed <= 0.0) speed = configuration_.default_speed; if (speed <= 0.0) speed = configuration_.default_speed;
ROS_DEBUG_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_move_srv_callback::Speed: " + std::to_string(speed) + " Width: " + std::to_string(req.width)); RCLCPP_DEBUG_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_move_srv_callback::Speed: " + std::to_string(speed) + " Width: " + std::to_string(req->width));
bool ret = false; bool ret = false;
bool function_ret = true; bool function_ret = true;
gripper_in_use_.lock(); gripper_in_use_.lock();
@@ -233,19 +224,19 @@ namespace qros
#else #else
try try
{ {
ret = gripper_sptr_->move(req.width, speed); ret = gripper_sptr_->move(req->width, speed);
}catch(franka::CommandException& e) }catch(franka::CommandException& e)
{ {
ROS_ERROR_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_move_srv_callback::CommandException::" + e.what()); RCLCPP_ERROR_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_move_srv_callback::CommandException::" + e.what());
function_ret = false; function_ret = false;
}catch(franka::NetworkException& e) }catch(franka::NetworkException& e)
{ {
ROS_ERROR_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_move_srv_callback::NetworkException::" + e.what()); RCLCPP_ERROR_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_move_srv_callback::NetworkException::" + e.what());
function_ret = false; function_ret = false;
} }
#endif #endif
gripper_in_use_.unlock(); gripper_in_use_.unlock();
res.success = ret; res->set__success(ret);
return function_ret; return function_ret;
} }
@@ -253,28 +244,25 @@ namespace qros
void EffectorDriverFrankaHand::_gripper_status_loop() void EffectorDriverFrankaHand::_gripper_status_loop()
{ {
status_loop_running_ = true; status_loop_running_ = true;
sas::Clock clock = sas::Clock(configuration_.thread_sampeling_time_ns); sas::Clock clock = sas::Clock(configuration_.thread_sampeling_time_s);
ROS_INFO_STREAM( RCLCPP_INFO_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Starting status loop.")
"["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Starting status loop.")
; ;
clock.init(); clock.init();
try try
{ {
while (status_loop_running_) while (status_loop_running_)
{ {
#ifdef BLOCK_READ_IN_USED
bool should_unlock = false; bool should_unlock = false;
#endif
if (!_is_connected()) throw std::runtime_error( if (!_is_connected()) throw std::runtime_error(
"[" + ros::this_node::getName() + "[" + std::string(node_->get_name())+
"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Robot is not connected."); "]::[EffectorDriverFrankaHand]::_gripper_status_loop::Robot is not connected.");
try try
{ {
#ifdef IN_TESTING #ifdef IN_TESTING
ROS_WARN_STREAM( RCLCPP_WARN_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::In testing mode.");
"["+ ros::this_node::getName()+ throw std::runtime_error("[" + std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::In testing mode.");
"]::[EffectorDriverFrankaHand]::_gripper_status_loop::In testing mode.");
throw std::runtime_error(
"[" + ros::this_node::getName() +
"]::[EffectorDriverFrankaHand]::_gripper_status_loop::In testing mode.");
#endif #endif
#ifdef BLOCK_READ_IN_USED #ifdef BLOCK_READ_IN_USED
gripper_in_use_.lock(); gripper_in_use_.lock();
@@ -284,23 +272,23 @@ namespace qros
#ifdef BLOCK_READ_IN_USED #ifdef BLOCK_READ_IN_USED
gripper_in_use_.unlock(); gripper_in_use_.unlock();
#endif #endif
sas_robot_driver_franka::GripperState msg; msg::GripperState msg;
msg.width = static_cast<float>(gripper_state.width); msg.set__width(static_cast<float>(gripper_state.width));
msg.max_width = static_cast<float>(gripper_state.max_width); msg.set__max_width(static_cast<float>(gripper_state.max_width));
msg.is_grasped = gripper_state.is_grasped; msg.set__is_grasped(gripper_state.is_grasped);
msg.temperature = gripper_state.temperature; msg.set__temperature(gripper_state.temperature);
msg.duration_ms = gripper_state.time.toMSec(); msg.set__duration_ms(gripper_state.time.toMSec());
gripper_status_publisher_.publish(msg); gripper_status_publisher_->publish(msg);
} }
catch (...) catch (...)
{ {
#ifdef BLOCK_READ_IN_USED #ifdef BLOCK_READ_IN_USED
if (should_unlock) gripper_in_use_.unlock(); if (should_unlock) gripper_in_use_.unlock();
#endif #endif
ROS_INFO_STREAM("["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Could not read gripper state. Unavailable."); RCLCPP_INFO_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Could not read gripper state. Unavailable.");
sas_robot_driver_franka::GripperState msg; msg::GripperState msg;
msg.width = 0.0; msg.width = 0.0;
gripper_status_publisher_.publish(msg); gripper_status_publisher_->publish(msg);
} }
clock.update_and_sleep(); clock.update_and_sleep();
@@ -309,19 +297,16 @@ namespace qros
} }
catch (std::exception& e) catch (std::exception& e)
{ {
ROS_ERROR_STREAM( RCLCPP_ERROR_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Exception::" + e.
"["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Exception::" + e.
what()); what());
status_loop_running_ = false; status_loop_running_ = false;
} }
catch (...) catch (...)
{ {
ROS_ERROR_STREAM( RCLCPP_ERROR_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+
"["+ ros::this_node::getName()+
"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Exception::Unknown exception."); "]::[EffectorDriverFrankaHand]::_gripper_status_loop::Exception::Unknown exception.");
status_loop_running_ = false; status_loop_running_ = false;
} }
ROS_INFO_STREAM( RCLCPP_INFO_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Exiting status loop.");
"["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Exiting status loop.");
} }
} // qros } // qros

View File

@@ -1,4 +1,33 @@
#include "robot_interface_hand.h" /*
# Copyright (c) 2023 Juan Jose Quiroz Omana
#
# This file is part of sas_robot_driver_franka.
#
# sas_robot_driver_franka is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sas_robot_driver_franka is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with sas_robot_driver. If not, see <https://www.gnu.org/licenses/>.
#
# ################################################################
#
# Author: Juan Jose Quiroz Omana, email: juanjqogm@gmail.com
#
# ################################################################
#
# Contributors:
# 1. Quenitin Lin
#
# ################################################################
*/
#include "sas_robot_driver_franka/robot_interface_hand.hpp"

View File

@@ -30,10 +30,7 @@
*/ */
#include "robot_interface_franka.h" #include <sas_robot_driver_franka/interfaces/robot_interface_franka.hpp>
#include <ros/this_node.h>
#include <rosconsole/macros_generated.h>
/** /**
@@ -313,6 +310,7 @@ void RobotInterfaceFranka::initialize()
initialize_flag_ = true; initialize_flag_ = true;
// initialize and set the robot to default behavior (collision behavior, impedance, etc) // initialize and set the robot to default behavior (collision behavior, impedance, etc)
// robot_sptr_->setDefaultBehavior();
setDefaultBehavior(*robot_sptr_); setDefaultBehavior(*robot_sptr_);
robot_sptr_->setCollisionBehavior( robot_sptr_->setCollisionBehavior(
franka_configuration_.lower_torque_threshold, franka_configuration_.lower_torque_threshold,

View File

@@ -31,18 +31,21 @@
*/ */
#include "../../include/sas_robot_driver_franka.h" #include <sas_robot_driver_franka/sas_robot_driver_franka.hpp>
#include "sas_clock/sas_clock.h" #include <sas_core/sas_clock.hpp>
#include <dqrobotics/utils/DQ_Math.h> #include <dqrobotics/utils/DQ_Math.h>
#include <ros/this_node.h>
#include <rosconsole/macros_generated.h>
namespace sas namespace sas
{ {
RobotDriverFranka::RobotDriverFranka(qros::RobotDynamicProvider* robot_dynamic_provider, const RobotDriverFrankaConfiguration &configuration, std::atomic_bool *break_loops): RobotDriverFranka::RobotDriverFranka(
const std::shared_ptr<Node> &node,
const std::shared_ptr<qros::RobotDynamicsServer> &robot_dynamic_provider, const RobotDriverFrankaConfiguration &configuration, std::atomic_bool *break_loops
):
RobotDriver(break_loops), RobotDriver(break_loops),
node_(node),
configuration_(configuration), configuration_(configuration),
robot_dynamic_provider_(robot_dynamic_provider), robot_dynamic_provider_sptr_(robot_dynamic_provider),
break_loops_(break_loops) break_loops_(break_loops)
{ {
joint_positions_.resize(7); joint_positions_.resize(7);
@@ -52,11 +55,10 @@ namespace sas
//joint_positions_buffer_.resize(8,0); //joint_positions_buffer_.resize(8,0);
//end_effector_pose_euler_buffer_.resize(7,0); //end_effector_pose_euler_buffer_.resize(7,0);
//end_effector_pose_homogenous_transformation_buffer_.resize(10,0); //end_effector_pose_homogenous_transformation_buffer_.resize(10,0);
std::cout<<configuration.ip_address<<std::endl; // std::cout<<configuration.ip_address<<std::endl;
RobotInterfaceFranka::MODE mode = RobotInterfaceFranka::MODE::None; RobotInterfaceFranka::MODE mode = RobotInterfaceFranka::MODE::None;
RCLCPP_INFO_STREAM(node_->get_logger(), "Mode: " << configuration_.mode);
std::cout<<configuration.mode<<std::endl;
if (configuration_.mode == std::string("None")) if (configuration_.mode == std::string("None"))
{ {
@@ -90,7 +92,7 @@ namespace sas
Vector3d force, torque; Vector3d force, torque;
std::tie(force, torque) = robot_driver_interface_sptr_->get_stiffness_force_torque(); std::tie(force, torque) = robot_driver_interface_sptr_->get_stiffness_force_torque();
const auto pose = robot_driver_interface_sptr_->get_stiffness_pose(); const auto pose = robot_driver_interface_sptr_->get_stiffness_pose();
robot_dynamic_provider_->publish_stiffness(pose, force, torque); robot_dynamic_provider_sptr_->publish_stiffness(pose, force, torque);
} }
@@ -143,9 +145,16 @@ namespace sas
VectorXd RobotDriverFranka::get_joint_positions() VectorXd RobotDriverFranka::get_joint_positions()
{ {
if(robot_driver_interface_sptr_->get_err_state()) { if(robot_driver_interface_sptr_->get_err_state()) {
ROS_ERROR_STREAM("["+ros::this_node::getName()+"]::driver interface error on:"+robot_driver_interface_sptr_->get_status_message()); RCLCPP_ERROR_STREAM(node_->get_logger(),
"["+std::string(node_->get_name())+"]::driver interface "
"error on:"+robot_driver_interface_sptr_->get_status_message());
break_loops_->store(true); break_loops_->store(true);
} }
if(!ok()) {
RCLCPP_WARN_STREAM(node_->get_logger(),
"["+std::string(node_->get_name())+"]::driver interface exit on shotdown signal recieved."
);
}
_update_stiffness_contact_and_pose(); _update_stiffness_contact_and_pose();
return robot_driver_interface_sptr_->get_joint_positions(); return robot_driver_interface_sptr_->get_joint_positions();
} }
@@ -160,7 +169,9 @@ namespace sas
{ {
robot_driver_interface_sptr_->set_target_joint_positions(desired_joint_positions_rad); robot_driver_interface_sptr_->set_target_joint_positions(desired_joint_positions_rad);
if(robot_driver_interface_sptr_->get_err_state()) { if(robot_driver_interface_sptr_->get_err_state()) {
ROS_ERROR_STREAM("["+ros::this_node::getName()+"]::driver interface error on:"+robot_driver_interface_sptr_->get_status_message()); RCLCPP_ERROR_STREAM(node_->get_logger(),
"["+std::string(node_->get_name())+"]::driver interface "
"error on:"+robot_driver_interface_sptr_->get_status_message());
break_loops_->store(true); break_loops_->store(true);
} }
} }
@@ -185,7 +196,9 @@ namespace sas
desired_joint_velocities_ = desired_joint_velocities; desired_joint_velocities_ = desired_joint_velocities;
robot_driver_interface_sptr_->set_target_joint_velocities(desired_joint_velocities); robot_driver_interface_sptr_->set_target_joint_velocities(desired_joint_velocities);
if(robot_driver_interface_sptr_->get_err_state()) { if(robot_driver_interface_sptr_->get_err_state()) {
ROS_ERROR_STREAM("["+ros::this_node::getName()+"]::driver interface error on:"+robot_driver_interface_sptr_->get_status_message()); RCLCPP_ERROR_STREAM(node_->get_logger(),
"["+std::string(node_->get_name())+"]::driver interface "
"error on:"+robot_driver_interface_sptr_->get_status_message());
break_loops_->store(true); break_loops_->store(true);
} }
} }

View File

@@ -0,0 +1,102 @@
/*
# Copyright (c) 2024 Quenitin Lin
#
# This file is part of sas_robot_driver_franka.
#
# sas_robot_driver_franka is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sas_robot_driver_franka is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with sas_robot_driver. If not, see <https://www.gnu.org/licenses/>.
#
# ################################################################
#
# Author: Quenitin Lin
#
# ################################################################
#
# Contributors:
# 1. Quenitin Lin
#
# ################################################################
*/
#include <memory>
#include <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_client.hpp>
using namespace qros;
RobotDynamicsClient::RobotDynamicsClient(const std::shared_ptr<Node> &node, const std::string& topic_prefix):
node_(node), topic_prefix_(topic_prefix == "GET_FROM_NODE"? node->get_name() : topic_prefix),
child_frame_id_(topic_prefix_ + "_stiffness_frame"), parent_frame_id_(topic_prefix_ + "_base"),
last_stiffness_force_(Vector3d::Zero()),
last_stiffness_torque_(Vector3d::Zero()),
last_stiffness_frame_pose_(0)
{
tf_buffer_ = std::make_unique<tf2_ros::Buffer>(node->get_clock());
tf_listener_ = std::make_shared<tf2_ros::TransformListener>(*tf_buffer_);
// Strip potential leading slash
if(child_frame_id_.front() == '/'){child_frame_id_ = child_frame_id_.substr(1);}
if(parent_frame_id_.front() == '/'){parent_frame_id_ = parent_frame_id_.substr(1);}
RCLCPP_INFO_STREAM(node_->get_logger(),
"["+ std::string(node_->get_name()) + "]::Initializing RobotDynamicsClient with prefix " + topic_prefix);
subscriber_cartesian_stiffness_ = node_->create_subscription<geometry_msgs::msg::WrenchStamped>(topic_prefix + "/get/cartesian_stiffness", 1,
std::bind(&RobotDynamicsClient::_callback_cartesian_stiffness, this, std::placeholders::_1)
);
}
void RobotDynamicsClient::_callback_cartesian_stiffness(const geometry_msgs::msg::WrenchStamped &msg)
{
last_stiffness_force_(0) = msg.wrench.force.x;
last_stiffness_force_(1) = msg.wrench.force.y;
last_stiffness_force_(2) = msg.wrench.force.z;
last_stiffness_torque_(0) = msg.wrench.torque.x;
last_stiffness_torque_(1) = msg.wrench.torque.y;
last_stiffness_torque_(2) = msg.wrench.torque.z;
try {
const auto transform_stamped = tf_buffer_->lookupTransform( parent_frame_id_, child_frame_id_, tf2::TimePointZero);
last_stiffness_frame_pose_ = _geometry_msgs_transform_to_dq(transform_stamped.transform);
} catch (tf2::TransformException &ex) {
RCLCPP_WARN_STREAM(node_->get_logger(), "["+ std::string(node_->get_name()) + "]::" + ex.what());
}
}
DQ RobotDynamicsClient::_geometry_msgs_transform_to_dq(const geometry_msgs::msg::Transform& transform)
{
const auto t = DQ(0,transform.translation.x,transform.translation.y,transform.translation.z);
const auto r = DQ(transform.rotation.w, transform.rotation.x, transform.rotation.y, transform.rotation.z);
return r + 0.5 * E_ * t * r;
}
VectorXd RobotDynamicsClient::get_stiffness_force()
{
if(!is_enabled()) throw std::runtime_error("[RobotDynamicsClient]::calling get_stiffness_force on uninitialized topic");
return last_stiffness_force_;
}
VectorXd RobotDynamicsClient::get_stiffness_torque()
{
if(!is_enabled()) throw std::runtime_error("[RobotDynamicsClient]::calling get_stiffness_torque on uninitialized topic");
return last_stiffness_torque_;
}
DQ RobotDynamicsClient::get_stiffness_frame_pose()
{
if(!is_enabled()) throw std::runtime_error("[RobotDynamicsClient]::calling get_stiffness_frame_pose on uninitialized Interface");
return last_stiffness_frame_pose_;
}
bool RobotDynamicsClient::is_enabled() const
{
if(last_stiffness_frame_pose_==0) return false;
return true;
}

View File

@@ -1,103 +0,0 @@
/*
# Copyright (c) 2023 Juan Jose Quiroz Omana
#
# This file is part of sas_robot_driver_franka.
#
# sas_robot_driver_franka is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sas_robot_driver_franka is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with sas_robot_driver. If not, see <https://www.gnu.org/licenses/>.
#
# ################################################################
#
# Author: Juan Jose Quiroz Omana, email: juanjqogm@gmail.com
#
# ################################################################
#
# Contributors:
# 1. Quenitin Lin
#
# ################################################################
*/
#include <robot_dynamic/qros_robot_dynamics_interface.h>
using namespace qros;
RobotDynamicInterface::RobotDynamicInterface(ros::NodeHandle &nodehandle, const std::string &node_prefix):
RobotDynamicInterface(nodehandle, nodehandle, node_prefix)
{
//Delegated
}
RobotDynamicInterface::RobotDynamicInterface(ros::NodeHandle &publisher_nodehandle, ros::NodeHandle &subscriber_nodehandle, const std::string &node_prefix):
node_prefix_(node_prefix),
child_frame_id_(node_prefix + "_stiffness_frame"),
parent_frame_id_(node_prefix + "_base"),
tf_buffer_(ros::Duration(BUFFER_DURATION_DEFAULT_S)),
tf_listener_(tf_buffer_, subscriber_nodehandle),
last_stiffness_force_(Vector3d::Zero()),
last_stiffness_torque_(Vector3d::Zero()),
last_stiffness_frame_pose_(0)
{
// Strip potential leading slash
if(child_frame_id_.front() == '/'){child_frame_id_ = child_frame_id_.substr(1);}
if(parent_frame_id_.front() == '/'){parent_frame_id_ = parent_frame_id_.substr(1);}
ROS_INFO_STREAM(ros::this_node::getName() + "::Initializing RobotDynamicInterface with prefix " + node_prefix);
subscriber_cartesian_stiffness_ = subscriber_nodehandle.subscribe(node_prefix_ + "/get/cartesian_stiffness", 1, &RobotDynamicInterface::_callback_cartesian_stiffness, this);
}
void RobotDynamicInterface::_callback_cartesian_stiffness(const geometry_msgs::WrenchStampedConstPtr &msg)
{
last_stiffness_force_(0) = msg->wrench.force.x;
last_stiffness_force_(1) = msg->wrench.force.y;
last_stiffness_force_(2) = msg->wrench.force.z;
last_stiffness_torque_(0) = msg->wrench.torque.x;
last_stiffness_torque_(1) = msg->wrench.torque.y;
last_stiffness_torque_(2) = msg->wrench.torque.z;
try {
const auto transform_stamped = tf_buffer_.lookupTransform( parent_frame_id_, child_frame_id_, ros::Time(0));
last_stiffness_frame_pose_ = _geometry_msgs_transform_to_dq(transform_stamped.transform);
} catch (tf2::TransformException &ex) {
ROS_WARN_STREAM(ros::this_node::getName() + "::" + ex.what());
}
}
DQ RobotDynamicInterface::_geometry_msgs_transform_to_dq(const geometry_msgs::Transform& transform)
{
const auto t = DQ(0,transform.translation.x,transform.translation.y,transform.translation.z);
const auto r = DQ(transform.rotation.w, transform.rotation.x, transform.rotation.y, transform.rotation.z);
return r + 0.5 * E_ * t * r;
}
VectorXd RobotDynamicInterface::get_stiffness_force()
{
if(!is_enabled()) throw std::runtime_error("[RobotDynamicInterface]::calling get_stiffness_force on uninitialized topic");
return last_stiffness_force_;
}
VectorXd RobotDynamicInterface::get_stiffness_torque()
{
if(!is_enabled()) throw std::runtime_error("[RobotDynamicInterface]::calling get_stiffness_torque on uninitialized topic");
return last_stiffness_torque_;
}
DQ RobotDynamicInterface::get_stiffness_frame_pose()
{
if(!is_enabled()) throw std::runtime_error("[RobotDynamicInterface]::calling get_stiffness_frame_pose on uninitialized Interface");
return last_stiffness_frame_pose_;
}
bool RobotDynamicInterface::is_enabled() const
{
if(last_stiffness_frame_pose_==0) return false;
return true;
}

View File

@@ -1,126 +0,0 @@
/*
# Copyright (c) 2023 Juan Jose Quiroz Omana
#
# This file is part of sas_robot_driver_franka.
#
# sas_robot_driver_franka is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sas_robot_driver_franka is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with sas_robot_driver. If not, see <https://www.gnu.org/licenses/>.
#
# ################################################################
#
# Author: Juan Jose Quiroz Omana, email: juanjqogm@gmail.com
#
# ################################################################
#
# Contributors:
# 1. Quenitin Lin
#
# ################################################################
*/
#include <robot_dynamic/qros_robot_dynamics_provider.h>
using namespace qros;
RobotDynamicProvider::RobotDynamicProvider(ros::NodeHandle &nodehandle, const std::string &node_prefix):
RobotDynamicProvider(nodehandle, nodehandle, node_prefix)
{
//Delegated
}
RobotDynamicProvider::RobotDynamicProvider(ros::NodeHandle &publisher_nodehandle, ros::NodeHandle &subscriber_nodehandle, const std::string &node_prefix):
node_prefix_(node_prefix),
child_frame_id_(node_prefix + "_stiffness_frame"),
parent_frame_id_(node_prefix + "_base"),
world_to_base_tf_(0)
{
// Strip potential leading slash
if(child_frame_id_.front() == '/'){child_frame_id_ = child_frame_id_.substr(1);}
if(parent_frame_id_.front() == '/'){parent_frame_id_ = parent_frame_id_.substr(1);}
ROS_INFO_STREAM(ros::this_node::getName() + "::Initializing RobotDynamicProvider with prefix " + node_prefix);
publisher_cartesian_stiffness_ = publisher_nodehandle.advertise<geometry_msgs::WrenchStamped>(node_prefix + "/get/cartesian_stiffness", 1);
}
geometry_msgs::Transform RobotDynamicProvider::_dq_to_geometry_msgs_transform(const DQ& pose)
{
geometry_msgs::Transform tf_msg;
const auto t = translation(pose);
const auto r = rotation(pose);
tf_msg.translation.x = t.q(1);
tf_msg.translation.y = t.q(2);
tf_msg.translation.z = t.q(3);
tf_msg.rotation.w = r.q(0);
tf_msg.rotation.x = r.q(1);
tf_msg.rotation.y = r.q(2);
tf_msg.rotation.z = r.q(3);
return tf_msg;
}
void RobotDynamicProvider::set_world_to_base_tf(const DQ& world_to_base_tf)
{
if(world_to_base_tf_==0)
{
world_to_base_tf_ = world_to_base_tf;
_publish_base_static_tf();
}else
{
throw std::runtime_error("The world to base transform has already been set");
}
}
void RobotDynamicProvider::_publish_base_static_tf()
{
geometry_msgs::TransformStamped base_tf;
base_tf.transform = _dq_to_geometry_msgs_transform(world_to_base_tf_);
base_tf.header.stamp = ros::Time::now();
base_tf.header.frame_id = WORLD_FRAME_ID;
base_tf.child_frame_id = parent_frame_id_;
static_base_tf_broadcaster_.sendTransform(base_tf);
}
void RobotDynamicProvider::publish_stiffness(const DQ& base_to_stiffness, const Vector3d& force, const Vector3d& torque)
{
std_msgs::Header header;
header.stamp = ros::Time::now();
header.seq = seq_++;
geometry_msgs::WrenchStamped msg;
msg.header = header;
msg.header.frame_id = child_frame_id_;
msg.wrench.force.x = force(0);
msg.wrench.force.y = force(1);
msg.wrench.force.z = force(2);
msg.wrench.torque.x = torque(0);
msg.wrench.torque.y = torque(1);
msg.wrench.torque.z = torque(2);
publisher_cartesian_stiffness_.publish(msg);
if(seq_ % REDUCE_TF_PUBLISH_RATE == 0)
{
geometry_msgs::TransformStamped tf_msg;
tf_msg.transform = _dq_to_geometry_msgs_transform(base_to_stiffness);
tf_msg.header = header;
tf_msg.header.frame_id = parent_frame_id_;
tf_msg.child_frame_id = child_frame_id_;
tf_broadcaster_.sendTransform(tf_msg);
}
}
bool RobotDynamicProvider::is_enabled() const
{
return true; //Always enabled
}

View File

@@ -32,29 +32,29 @@
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <pybind11/eigen.h> #include <pybind11/eigen.h>
#include <robot_dynamic/qros_robot_dynamics_provider.h> #include <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_client.hpp>
#include <robot_dynamic/qros_robot_dynamics_interface.h> #include <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_server.hpp>
namespace py = pybind11; namespace py = pybind11;
using RDI = qros::RobotDynamicInterface; using RDC = qros::RobotDynamicsClient;
using RDP = qros::RobotDynamicProvider; using RDS = qros::RobotDynamicsServer;
PYBIND11_MODULE(_qros_robot_dynamic, m) PYBIND11_MODULE(_qros_franka_robot_dynamic, m)
{ {
py::class_<RDI>(m, "RobotDynamicsInterface") py::class_<RDC>(m, "RobotDynamicsClient")
.def(py::init<const std::string&>()) .def(py::init<const std::shared_ptr<rclcpp::Node>&,const std::string&>())
.def("get_stiffness_force",&RDI::get_stiffness_force) .def("get_stiffness_force",&RDC::get_stiffness_force)
.def("get_stiffness_torque",&RDI::get_stiffness_torque) .def("get_stiffness_torque",&RDC::get_stiffness_torque)
.def("get_stiffness_frame_pose",&RDI::get_stiffness_frame_pose) .def("get_stiffness_frame_pose",&RDC::get_stiffness_frame_pose)
.def("is_enabled",&RDI::is_enabled,"Returns true if the RobotDynamicInterface is enabled.") .def("is_enabled",&RDC::is_enabled,"Returns true if the RobotDynamicInterface is enabled.")
.def("get_topic_prefix",&RDI::get_topic_prefix); .def("get_topic_prefix",&RDC::get_topic_prefix);
py::class_<RDP>(m, "RobotDynamicsProvider") py::class_<RDS>(m, "RobotDynamicsServer")
.def(py::init<const std::string&>()) .def(py::init<const std::shared_ptr<rclcpp::Node>&,const std::string&>())
.def("publish_stiffness",&RDP::publish_stiffness) .def("publish_stiffness",&RDS::publish_stiffness)
.def("set_world_to_base_tf", &RDP::set_world_to_base_tf) .def("set_world_to_base_tf", &RDS::set_world_to_base_tf)
.def("is_enabled",&RDP::is_enabled,"Returns true if the RobotDynamicProvider is enabled.") .def("is_enabled",&RDS::is_enabled,"Returns true if the RobotDynamicProvider is enabled.")
.def("get_topic_prefix",&RDP::get_topic_prefix); .def("get_topic_prefix",&RDS::get_topic_prefix);
} }

View File

@@ -0,0 +1,120 @@
/*
# Copyright (c) 2024 Quenitin Lin
#
# This file is part of sas_robot_driver_franka.
#
# sas_robot_driver_franka is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sas_robot_driver_franka is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with sas_robot_driver. If not, see <https://www.gnu.org/licenses/>.
#
# ################################################################
#
# Author: Quenitin Lin
#
# ################################################################
#
# Contributors:
# 1. Quenitin Lin
#
# ################################################################
*/
#include <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_server.hpp>
using namespace qros;
RobotDynamicsServer::RobotDynamicsServer(const std::shared_ptr<Node> &node, const std::string& topic_prefix):
node_(node), topic_prefix_(topic_prefix == "GET_FROM_NODE"? node->get_name() : topic_prefix),
child_frame_id_(topic_prefix_ + "_stiffness_frame"), parent_frame_id_(topic_prefix_ + "_base"),
tf_broadcaster_(std::make_shared<tf2_ros::TransformBroadcaster>(node_)),
static_base_tf_broadcaster_(std::make_shared<tf2_ros::StaticTransformBroadcaster>(node_)),
world_to_base_tf_(0)
{
// Strip potential leading slash
if(child_frame_id_.front() == '/'){child_frame_id_ = child_frame_id_.substr(1);}
if(parent_frame_id_.front() == '/'){parent_frame_id_ = parent_frame_id_.substr(1);}
RCLCPP_INFO_STREAM(node_->get_logger(),
"["+ std::string(node_->get_name()) + "]::Initializing RobotDynamicsServer with prefix " + topic_prefix);
publisher_cartesian_stiffness_ = node_->create_publisher<geometry_msgs::msg::WrenchStamped>(topic_prefix + "/get/cartesian_stiffness", 1);
}
geometry_msgs::msg::Transform RobotDynamicsServer::_dq_to_geometry_msgs_transform(const DQ& pose)
{
geometry_msgs::msg::Transform tf_msg;
const auto t = translation(pose);
const auto r = rotation(pose);
tf_msg.translation.x = t.q(1);
tf_msg.translation.y = t.q(2);
tf_msg.translation.z = t.q(3);
tf_msg.rotation.w = r.q(0);
tf_msg.rotation.x = r.q(1);
tf_msg.rotation.y = r.q(2);
tf_msg.rotation.z = r.q(3);
return tf_msg;
}
void RobotDynamicsServer::set_world_to_base_tf(const DQ& world_to_base_tf)
{
if(world_to_base_tf_==0)
{
world_to_base_tf_ = world_to_base_tf;
_publish_base_static_tf();
}else
{
throw std::runtime_error("["+ std::string(node_->get_name()) + "]::[RobotDynamicsServer]::The world to base transform has already been set");
}
}
void RobotDynamicsServer::_publish_base_static_tf()
{
geometry_msgs::msg::TransformStamped base_tf;
base_tf.set__transform(_dq_to_geometry_msgs_transform(world_to_base_tf_));
std_msgs::msg::Header header;
header.set__stamp(node_->now());
header.set__frame_id(WORLD_FRAME_ID);
base_tf.set__header(header);
base_tf.set__child_frame_id(parent_frame_id_);
static_base_tf_broadcaster_->sendTransform(base_tf);
}
void RobotDynamicsServer::publish_stiffness(const DQ& base_to_stiffness, const Vector3d& force, const Vector3d& torque)
{
std_msgs::msg::Header header;
header.set__stamp(node_->now());
geometry_msgs::msg::WrenchStamped msg;
msg.set__header(header);
msg.header.set__frame_id(child_frame_id_);
msg.wrench.force.set__x(force(0));
msg.wrench.force.set__y(force(1));
msg.wrench.force.set__z(force(2));
msg.wrench.torque.set__x(torque(0));
msg.wrench.torque.set__y(torque(1));
msg.wrench.torque.set__z(torque(2));
publisher_cartesian_stiffness_->publish(msg);
if(seq_ % REDUCE_TF_PUBLISH_RATE == 0)
{
header.set__frame_id(parent_frame_id_);
geometry_msgs::msg::TransformStamped tf_msg;
tf_msg.set__transform(_dq_to_geometry_msgs_transform(base_to_stiffness));
tf_msg.set__header(header);
tf_msg.set__child_frame_id(child_frame_id_);
tf_broadcaster_->sendTransform(tf_msg);
}
}
bool RobotDynamicsServer::is_enabled() const
{
return true; //Always enabled
}

View File

@@ -26,6 +26,9 @@
# 1. Juan Jose Quiroz Omana (juanjqogm@gmail.com) # 1. Juan Jose Quiroz Omana (juanjqogm@gmail.com)
# - Adapted from sas_robot_driver_denso_node.cpp # - Adapted from sas_robot_driver_denso_node.cpp
# (https://github.com/SmartArmStack/sas_robot_driver_denso/blob/master/src/sas_robot_driver_denso_node.cpp) # (https://github.com/SmartArmStack/sas_robot_driver_denso/blob/master/src/sas_robot_driver_denso_node.cpp)
# 2. Quentin Lin (qlin1806@g.ecc.u-tokyo.ac.jp)
# - Adapted for simplify operation
# - porting to ROS2
# #
# ################################################################ # ################################################################
*/ */
@@ -36,10 +39,9 @@
#include <exception> #include <exception>
#include <dqrobotics/utils/DQ_Math.h> #include <dqrobotics/utils/DQ_Math.h>
//#include <dqrobotics/interfaces/json11/DQ_JsonReader.h> //#include <dqrobotics/interfaces/json11/DQ_JsonReader.h>
#include <sas_common/sas_common.h> #include <sas_common/sas_common.hpp>
#include <sas_conversions/eigen3_std_conversions.h> #include <sas_conversions/eigen3_std_conversions.hpp>
#include <sas_robot_driver/sas_robot_driver_ros.h> #include <sas_robot_driver_franka/coppelia/sas_robot_driver_coppelia.hpp>
#include "coppelia/sas_robot_driver_coppelia.h"
/********************************************* /*********************************************
* SIGNAL HANDLER * SIGNAL HANDLER
@@ -52,52 +54,51 @@ void sig_int_handler(int)
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if(signal(SIGINT, sig_int_handler) == SIG_ERR) if(signal(SIGINT, sig_int_handler) == SIG_ERR)
{ {
throw std::runtime_error(ros::this_node::getName() + "::Error setting the signal int handler."); throw std::runtime_error("Error setting the signal int handler.");
} }
ros::init(argc, argv, "sas_robot_driver_coppelia_node", ros::init_options::NoSigintHandler); rclcpp::init(argc,argv,rclcpp::InitOptions(),rclcpp::SignalHandlerOptions::None);
ROS_WARN("====================================================================="); auto context = rclcpp::contexts::get_global_default_context();
ROS_WARN("----------------------Juan Jose Quiroz Omana------------------------");
ROS_WARN("====================================================================="); auto node = std::make_shared<rclcpp::Node>("sas_robot_driver_franka_coppelia_node");
ROS_INFO_STREAM(ros::this_node::getName()+"::Loading parameters from parameter server.");
const auto node_name = std::string(node->get_name());
RCLCPP_WARN(node->get_logger(),"=====================================================================");
RCLCPP_WARN(node->get_logger(),"-----------------Adapted by Quentin Lin ------------------------");
RCLCPP_WARN(node->get_logger(),"=====================================================================");
RCLCPP_INFO_STREAM_ONCE(node->get_logger(),":Loading parameters from parameter server.");
ros::NodeHandle nh; qros::RobotDriverCoppeliaConfiguration robot_driver_coppelia_configuration;
sas::RobotDriverCoppeliaConfiguration robot_driver_coppelia_configuration; sas::get_ros_parameter(node,"thread_sampling_time_sec",robot_driver_coppelia_configuration.thread_sampling_time_sec);
sas::get_ros_parameter(node,"vrep_ip",robot_driver_coppelia_configuration.vrep_ip);
sas::get_ros_param(nh,"/robot_ip_address",robot_driver_coppelia_configuration.ip); sas::get_ros_parameter(node,"vrep_port",robot_driver_coppelia_configuration.vrep_port);
sas::get_ros_param(nh,"/robot_mode", robot_driver_coppelia_configuration.robot_mode); sas::get_ros_parameter(node,"vrep_joint_names", robot_driver_coppelia_configuration.vrep_joint_names);
sas::get_ros_param(nh,"/vrep_port", robot_driver_coppelia_configuration.port); sas::get_ros_parameter(node,"vrep_dynamically_enabled", robot_driver_coppelia_configuration.vrep_dynamically_enabled);
sas::get_ros_param(nh,"/vrep_robot_joint_names", robot_driver_coppelia_configuration.jointnames); sas::get_ros_parameter(node,"robot_mode", robot_driver_coppelia_configuration.robot_mode);
sas::get_ros_param(nh,"/mirror_mode", robot_driver_coppelia_configuration.mirror_mode); sas::get_ros_parameter(node,"using_real_robot", robot_driver_coppelia_configuration.using_real_robot);
sas::get_ros_param(nh, "/real_robot_topic_prefix", robot_driver_coppelia_configuration.real_robot_topic_prefix); sas::get_ros_parameter(node,"robot_topic_prefix", robot_driver_coppelia_configuration.robot_topic_prefix);
sas::RobotDriverROSConfiguration robot_driver_ros_configuration; sas::get_ros_parameter(node,"robot_parameter_file_path", robot_driver_coppelia_configuration.robot_parameter_file_path);
sas::get_ros_param(nh,"/thread_sampling_time_nsec",robot_driver_ros_configuration.thread_sampling_time_nsec);
sas::get_ros_param(nh,"/q_min",robot_driver_ros_configuration.q_min);
sas::get_ros_param(nh,"/q_max",robot_driver_ros_configuration.q_max);
robot_driver_ros_configuration.robot_driver_provider_prefix = ros::this_node::getName();
try try
{ {
ROS_INFO_STREAM(ros::this_node::getName()+"::Instantiating Coppelia robot."); RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"::Instantiating Coppelia robot mirror.");
sas::RobotDriverCoppelia robot_driver_coppelia(robot_driver_coppelia_configuration, qros::RobotDriverCoppelia robot_driver_coppelia(node, robot_driver_coppelia_configuration,
&kill_this_process); &kill_this_process);
ROS_INFO_STREAM(ros::this_node::getName()+"::Instantiating RobotDriverROS.");
sas::RobotDriverROS robot_driver_ros(nh, return robot_driver_coppelia.start_control_loop();
&robot_driver_coppelia,
robot_driver_ros_configuration,
&kill_this_process);
robot_driver_ros.control_loop();
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
ROS_ERROR_STREAM(ros::this_node::getName() + "::Exception::" + e.what()); kill_this_process = true;
RCLCPP_ERROR_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Exception::" + e.what());
shutdown(context, "Exception in main function: " + std::string(e.what()));
return -1;
} }

View File

@@ -1,4 +0,0 @@
"""
"""
from _qros_robot_dynamic import RobotDynamicsInterface, RobotDynamicsProvider
from .franka_gripper_interface import FrankaGripperInterface

View File

@@ -33,10 +33,9 @@
#include <exception> #include <exception>
#include <dqrobotics/utils/DQ_Math.h> #include <dqrobotics/utils/DQ_Math.h>
#include <sas_common/sas_common.h> #include <sas_common/sas_common.hpp>
#include <sas_conversions/eigen3_std_conversions.h> // #include <sas_conversions/eigen3_std_conversions.hpp>
#include <sas_robot_driver/sas_robot_driver_ros.h> #include <sas_robot_driver_franka/interfaces/qros_effector_driver_franka_hand.hpp>
#include "hand/qros_effector_driver_franka_hand.h"
/********************************************* /*********************************************
@@ -52,14 +51,14 @@ void sig_int_handler(int)
template<typename T> template<typename T>
void get_optional_parameter(const std::string &node_prefix, ros::NodeHandle &nh, const std::string &param_name, T &param) void get_optional_parameter(std::shared_ptr<Node> node, const std::string &param_name, T &param)
{ {
if(nh.hasParam(node_prefix + param_name)) if(node->has_parameter(param_name))
{ {
sas::get_ros_param(nh,param_name,param); sas::get_ros_parameter(node,param_name,param);
}else }else
{ {
ROS_INFO_STREAM(ros::this_node::getName() + "::Parameter " + param_name + " not found. Using default value. " + std::to_string(param)); RCLCPP_INFO_STREAM(node->get_logger(), "["+std::string(node->get_name())+"]:Parameter " + param_name + " not found. Using default value. " + std::to_string(param));
} }
} }
@@ -69,55 +68,53 @@ int main(int argc, char **argv)
{ {
if(signal(SIGINT, sig_int_handler) == SIG_ERR) if(signal(SIGINT, sig_int_handler) == SIG_ERR)
{ {
throw std::runtime_error(ros::this_node::getName() + "::Error setting the signal int handler."); throw std::runtime_error("Error setting the signal int handler.");
} }
ros::init(argc, argv, "sas_robot_driver_franka_hand_node", ros::init_options::NoSigintHandler);
ROS_WARN("=====================================================================");
ROS_WARN("---------------------------Quentin Lin-------------------------------");
ROS_WARN("=====================================================================");
ROS_INFO_STREAM(ros::this_node::getName()+"::Loading parameters from parameter server.");
const std::string& effector_driver_provider_prefix = ros::this_node::getName();
rclcpp::init(argc,argv,rclcpp::InitOptions(),rclcpp::SignalHandlerOptions::None);
auto node = std::make_shared<rclcpp::Node>("sas_robot_driver_franka_hand_node");
const auto node_name = std::string(node->get_name());
RCLCPP_WARN(node->get_logger(),"=====================================================================");
RCLCPP_WARN(node->get_logger(),"---------------------------Quentin Lin-------------------------------");
RCLCPP_WARN(node->get_logger(),"=====================================================================");
RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Loading parameters from parameter server.");
ros::NodeHandle nh;
qros::EffectorDriverFrankaHandConfiguration robot_driver_franka_hand_configuration; qros::EffectorDriverFrankaHandConfiguration robot_driver_franka_hand_configuration;
sas::get_ros_parameter(node,"robot_ip_address",robot_driver_franka_hand_configuration.robot_ip);
sas::get_ros_param(nh,"/robot_ip_address",robot_driver_franka_hand_configuration.robot_ip); sas::get_ros_parameter(node,"thread_sampling_time_sec",robot_driver_franka_hand_configuration.thread_sampeling_time_s);
sas::get_ros_parameter(node,"default_force",robot_driver_franka_hand_configuration.default_force);
get_optional_parameter(effector_driver_provider_prefix,nh,"/thread_sampling_time_nsec",robot_driver_franka_hand_configuration.thread_sampeling_time_ns); sas::get_ros_parameter(node,"default_speed",robot_driver_franka_hand_configuration.default_speed);
get_optional_parameter(effector_driver_provider_prefix,nh,"/default_force",robot_driver_franka_hand_configuration.default_force); sas::get_ros_parameter(node,"default_epsilon_inner",robot_driver_franka_hand_configuration.default_epsilon_inner);
get_optional_parameter(effector_driver_provider_prefix,nh,"/default_speed",robot_driver_franka_hand_configuration.default_speed); sas::get_ros_parameter(node,"default_epsilon_outer",robot_driver_franka_hand_configuration.default_epsilon_outer);
get_optional_parameter(effector_driver_provider_prefix,nh,"/default_epsilon_inner",robot_driver_franka_hand_configuration.default_epsilon_inner);
get_optional_parameter(effector_driver_provider_prefix,nh,"/default_epsilon_outer",robot_driver_franka_hand_configuration.default_epsilon_outer);
qros::EffectorDriverFrankaHand franka_hand_driver( qros::EffectorDriverFrankaHand franka_hand_driver(
effector_driver_provider_prefix, node_name,
robot_driver_franka_hand_configuration, robot_driver_franka_hand_configuration,
nh, node,
&kill_this_process &kill_this_process
); );
try try
{ {
ROS_INFO_STREAM(ros::this_node::getName()+"::Instantiating Franka hand."); RCLCPP_INFO_STREAM(node->get_logger(),"["+node_name+"]::Instantiating Franka hand.");
franka_hand_driver.connect(); franka_hand_driver.connect();
franka_hand_driver.initialize(); franka_hand_driver.initialize();
RCLCPP_INFO_STREAM(node->get_logger(),"["+node_name+"]::Starting control loop.");
ROS_INFO_STREAM(ros::this_node::getName()+"::Instantiating control loop.");
franka_hand_driver.start_control_loop(); franka_hand_driver.start_control_loop();
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
ROS_ERROR_STREAM(ros::this_node::getName() + "::Exception::" + e.what()); RCLCPP_ERROR_STREAM(node->get_logger(), "["+node_name+"]::Exception::" + e.what());
}catch (...) }catch (...)
{ {
ROS_ERROR_STREAM(ros::this_node::getName() + "::Exception::Unknown exception."); RCLCPP_ERROR_STREAM(node->get_logger(), "["+node_name+"]::Exception::Unknown exception.");
} }
ROS_INFO_STREAM(ros::this_node::getName()+"::Exiting..."); RCLCPP_INFO_STREAM(node->get_logger(),"["+node_name+"]::Exiting...");
franka_hand_driver.deinitialize(); franka_hand_driver.deinitialize();
ROS_INFO_STREAM(ros::this_node::getName()+"::deinitialized."); RCLCPP_INFO_STREAM(node->get_logger(),"["+node_name+"]::Deinitialized.");
franka_hand_driver.disconnect(); franka_hand_driver.disconnect();
ROS_INFO_STREAM(ros::this_node::getName()+"::disconnected."); RCLCPP_INFO_STREAM(node->get_logger(),"["+node_name+"]::Disconnected.");
return 0; return 0;

View File

@@ -26,6 +26,8 @@
# 1. Juan Jose Quiroz Omana (juanjqogm@gmail.com) # 1. Juan Jose Quiroz Omana (juanjqogm@gmail.com)
# - Adapted from sas_robot_driver_denso_node.cpp # - Adapted from sas_robot_driver_denso_node.cpp
# (https://github.com/SmartArmStack/sas_robot_driver_denso/blob/master/src/sas_robot_driver_denso_node.cpp) # (https://github.com/SmartArmStack/sas_robot_driver_denso/blob/master/src/sas_robot_driver_denso_node.cpp)
# 2. Quentin Lin
# - Adaption to ROS2
# #
# ################################################################ # ################################################################
*/ */
@@ -36,11 +38,11 @@
#include <exception> #include <exception>
#include <dqrobotics/utils/DQ_Math.h> #include <dqrobotics/utils/DQ_Math.h>
#include <dqrobotics/interfaces/json11/DQ_JsonReader.h> #include <dqrobotics/interfaces/json11/DQ_JsonReader.h>
#include <sas_common/sas_common.h> #include <sas_common/sas_common.hpp>
#include <sas_conversions/eigen3_std_conversions.h> #include <sas_conversions/eigen3_std_conversions.hpp>
#include <sas_robot_driver/sas_robot_driver_ros.h> #include <sas_robot_driver/sas_robot_driver_ros.hpp>
#include "sas_robot_driver_franka.h" #include <sas_robot_driver_franka/sas_robot_driver_franka.hpp>
#include <robot_dynamic/qros_robot_dynamics_provider.h> #include <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_server.hpp>
/********************************************* /*********************************************
@@ -74,90 +76,108 @@ std::array<T, N> std_vec_to_std_array(const std::vector<T>& vector)
} }
return array; return array;
} }
VectorXd std_vec_to_eigen_vector(const std::vector<double>& vector)
{
VectorXd eigen_vector(vector.size());
for(std::size_t i = 0; i < vector.size(); i++)
{
eigen_vector(i) = vector[i];
}
return eigen_vector;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if(signal(SIGINT, sig_int_handler) == SIG_ERR) if(signal(SIGINT, sig_int_handler) == SIG_ERR)
{ {
throw std::runtime_error(ros::this_node::getName() + "::Error setting the signal int handler."); throw std::runtime_error("Error setting the signal int handler.");
} }
ros::init(argc, argv, "sas_robot_driver_franka_node", ros::init_options::NoSigintHandler); rclcpp::init(argc,argv,rclcpp::InitOptions(),rclcpp::SignalHandlerOptions::None);
ROS_WARN("====================================================================="); auto node = std::make_shared<rclcpp::Node>("sas_robot_driver_franka_node");
ROS_WARN("----------------------Juan Jose Quiroz Omana------------------------");
ROS_WARN("=====================================================================");
ROS_INFO_STREAM(ros::this_node::getName()+"::Loading parameters from parameter server.");
const auto node_name = std::string(node->get_name());
RCLCPP_WARN(node->get_logger(),"=====================================================================");
RCLCPP_WARN(node->get_logger(),"-----------------Adapted by Quentin Lin ------------------------");
RCLCPP_WARN(node->get_logger(),"=====================================================================");
RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Loading parameters from parameter server.");
ros::NodeHandle nh;
sas::RobotDriverFrankaConfiguration robot_driver_franka_configuration; sas::RobotDriverFrankaConfiguration robot_driver_franka_configuration;
RobotInterfaceFranka::FrankaInterfaceConfiguration franka_interface_configuration; RobotInterfaceFranka::FrankaInterfaceConfiguration franka_interface_configuration;
sas::get_ros_param(nh,"/robot_ip_address",robot_driver_franka_configuration.ip_address); sas::get_ros_parameter(node,"robot_ip_address",robot_driver_franka_configuration.ip_address);
sas::get_ros_param(nh,"/robot_mode", robot_driver_franka_configuration.mode); sas::get_ros_parameter(node,"robot_mode", robot_driver_franka_configuration.mode);
double upper_scale_factor = 1.0; double upper_scale_factor = 1.0;
std::vector<std::string> all_params; std::vector<std::string> all_params;
if(nh.hasParam(ros::this_node::getName()+"/force_upper_limits_scaling_factor"))
{ try {
sas::get_ros_param(nh,"/force_upper_limits_scaling_factor",upper_scale_factor); sas::get_ros_parameter(node,"force_upper_limits_scaling_factor",upper_scale_factor);
ROS_WARN_STREAM(ros::this_node::getName()+"::Set force upper limits scaling factor: " << upper_scale_factor); RCLCPP_WARN_STREAM_ONCE(node->get_logger(),"Set force upper limits scaling factor: " << upper_scale_factor);
}catch(...) {
RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"Force upper limits scaling factor is not set.");
} }
if(nh.hasParam(ros::this_node::getName()+"/upper_torque_threshold")) {
ROS_INFO_STREAM(ros::this_node::getName()+"::Upper torque threshold override and set."); try{node->declare_parameter<std::vector<double>>("upper_torque_threshold");}catch (...){}
if(node->has_parameter("upper_torque_threshold")) {
RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Upper torque threshold override and set.");
std::vector<double> upper_torque_threshold_std_vec; std::vector<double> upper_torque_threshold_std_vec;
sas::get_ros_param(nh,"/upper_torque_threshold",upper_torque_threshold_std_vec); sas::get_ros_parameter(node,"upper_torque_threshold",upper_torque_threshold_std_vec);
franka_interface_configuration.upper_torque_threshold = std_vec_to_std_array<double,7>(upper_torque_threshold_std_vec); franka_interface_configuration.upper_torque_threshold = std_vec_to_std_array<double,7>(upper_torque_threshold_std_vec);
}else { }else {
ROS_INFO_STREAM(ros::this_node::getName()+"::Upper torque threshold not set. Using default with value scalling."); RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Upper torque threshold not set. Using default with value scalling.");
franka_interface_configuration.upper_torque_threshold = apply_scale_to_std_array(franka_interface_configuration.upper_torque_threshold, upper_scale_factor); franka_interface_configuration.upper_torque_threshold = apply_scale_to_std_array(franka_interface_configuration.upper_torque_threshold, upper_scale_factor);
} }
if(nh.hasParam(ros::this_node::getName()+"/upper_force_threshold")) { try{node->declare_parameter<std::vector<double>>("upper_force_threshold");}catch (...){}
ROS_INFO_STREAM(ros::this_node::getName()+"::Upper force threshold override and set."); if(node->has_parameter("upper_force_threshold")) {
RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Upper force threshold override and set.");
std::vector<double> upper_torque_threshold_std_vec; std::vector<double> upper_torque_threshold_std_vec;
sas::get_ros_param(nh,"/upper_force_threshold",upper_torque_threshold_std_vec); sas::get_ros_parameter(node,"upper_force_threshold",upper_torque_threshold_std_vec);
franka_interface_configuration.upper_force_threshold = std_vec_to_std_array<double,6>(upper_torque_threshold_std_vec); franka_interface_configuration.upper_force_threshold = std_vec_to_std_array<double,6>(upper_torque_threshold_std_vec);
}else { }else {
ROS_INFO_STREAM(ros::this_node::getName()+"::Upper force threshold not set. Using default with value scalling."); RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Upper force threshold not set. Using default with value scalling.");
franka_interface_configuration.upper_force_threshold = apply_scale_to_std_array(franka_interface_configuration.upper_force_threshold, upper_scale_factor); franka_interface_configuration.upper_force_threshold = apply_scale_to_std_array(franka_interface_configuration.upper_force_threshold, upper_scale_factor);
} }
if(nh.hasParam(ros::this_node::getName()+"/robot_parameter_file_path")) try{node->declare_parameter<std::string>("robot_parameter_file_path");}catch (...){}
if(node->has_parameter("robot_parameter_file_path"))
{ {
std::string robot_parameter_file_path; std::string robot_parameter_file_path;
sas::get_ros_param(nh,"/robot_parameter_file_path",robot_parameter_file_path); sas::get_ros_parameter(node,"robot_parameter_file_path",robot_parameter_file_path);
ROS_INFO_STREAM(ros::this_node::getName()+"::Loading robot parameters from file: " + robot_parameter_file_path); RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Loading robot parameters from file: " + robot_parameter_file_path);
const auto robot = DQ_JsonReader::get_from_json<DQ_SerialManipulatorDH>(robot_parameter_file_path); const auto robot = DQ_JsonReader::get_from_json<DQ_SerialManipulatorDH>(robot_parameter_file_path);
robot_driver_franka_configuration.robot_reference_frame = robot.get_reference_frame(); robot_driver_franka_configuration.robot_reference_frame = robot.get_reference_frame();
}else{ROS_INFO_STREAM(ros::this_node::getName()+"::Robot parameter file path not set. Robot Model Unknow.");} }else{RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Robot parameter file path not set. Robot Model Unknow.");}
robot_driver_franka_configuration.interface_configuration = franka_interface_configuration; robot_driver_franka_configuration.interface_configuration = franka_interface_configuration;
sas::RobotDriverROSConfiguration robot_driver_ros_configuration; sas::RobotDriverROSConfiguration robot_driver_ros_configuration;
sas::get_ros_param(nh,"/thread_sampling_time_nsec",robot_driver_ros_configuration.thread_sampling_time_nsec); sas::get_ros_parameter(node,"thread_sampling_time_sec",robot_driver_ros_configuration.thread_sampling_time_sec);
sas::get_ros_param(nh,"/q_min",robot_driver_ros_configuration.q_min); sas::get_ros_parameter(node,"q_min",robot_driver_ros_configuration.q_min);
sas::get_ros_param(nh,"/q_max",robot_driver_ros_configuration.q_max); sas::get_ros_parameter(node,"q_max",robot_driver_ros_configuration.q_max);
// initialize the robot dynamic provider // initialize the robot dynamic provider
robot_driver_ros_configuration.robot_driver_provider_prefix = ros::this_node::getName(); robot_driver_ros_configuration.robot_driver_provider_prefix = node_name;
qros::RobotDynamicProvider robot_dynamic_provider(nh, robot_driver_ros_configuration.robot_driver_provider_prefix); std::shared_ptr<qros::RobotDynamicsServer> robot_dynamic_provider_ptr = std::make_shared<qros::RobotDynamicsServer>(node, robot_driver_ros_configuration.robot_driver_provider_prefix);
if(robot_driver_franka_configuration.robot_reference_frame!=0) if(robot_driver_franka_configuration.robot_reference_frame!=0)
{ {
robot_dynamic_provider.set_world_to_base_tf(robot_driver_franka_configuration.robot_reference_frame); robot_dynamic_provider_ptr->set_world_to_base_tf(robot_driver_franka_configuration.robot_reference_frame);
} }
try try
{ {
ROS_INFO_STREAM(ros::this_node::getName()+"::Instantiating Franka robot."); RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Instantiating Franka robot.");
sas::RobotDriverFranka robot_driver_franka( auto robot_driver_franka = std::make_shared<sas::RobotDriverFranka>(
&robot_dynamic_provider, node,
robot_dynamic_provider_ptr,
robot_driver_franka_configuration, robot_driver_franka_configuration,
&kill_this_process &kill_this_process
); );
//robot_driver_franka.set_joint_limits({qmin, qmax}); std::tuple<VectorXd, VectorXd> joint_limits = {std_vec_to_eigen_vector(robot_driver_ros_configuration.q_min), std_vec_to_eigen_vector(robot_driver_ros_configuration.q_max)};
ROS_INFO_STREAM(ros::this_node::getName()+"::Instantiating RobotDriverROS."); robot_driver_franka -> set_joint_limits(joint_limits);
sas::RobotDriverROS robot_driver_ros(nh, RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Instantiating RobotDriverROS.");
&robot_driver_franka, sas::RobotDriverROS robot_driver_ros(node,
robot_driver_franka,
robot_driver_ros_configuration, robot_driver_ros_configuration,
&kill_this_process); &kill_this_process);
robot_driver_ros.control_loop(); robot_driver_ros.control_loop();
@@ -165,7 +185,7 @@ int main(int argc, char **argv)
catch (const std::exception& e) catch (const std::exception& e)
{ {
kill_this_process = true; kill_this_process = true;
ROS_ERROR_STREAM(ros::this_node::getName() + "::Exception::" + e.what()); RCLCPP_ERROR_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Exception::" + e.what());
} }

View File

@@ -1,7 +0,0 @@
float32 width
float32 speed
float32 force
float32 epsilon_inner
float32 epsilon_outer
---
bool success

View File

@@ -1,4 +0,0 @@
float32 width
float32 speed
---
bool success