Compare commits
14 Commits
master
...
35131ed59e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35131ed59e | ||
| fe5bb31873 | |||
| e2f7830e01 | |||
| 75e00b3111 | |||
| 0358b851df | |||
| 27b89070aa | |||
| 9b2061ba01 | |||
| 900f6aa2e1 | |||
| 94a32a0f0c | |||
| 058c123170 | |||
| db4b1ccd58 | |||
| 66a45b9ece | |||
| 7dfd4d40b8 | |||
| f5552be8d6 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,3 @@
|
|||||||
.idea
|
.idea
|
||||||
CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
cmake-build*
|
cmake-build*
|
||||||
build/
|
|
||||||
**/__pycache__/
|
|
||||||
|
|||||||
346
CMakeLists.txt
346
CMakeLists.txt
@@ -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,146 +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
|
|
||||||
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)
|
|
||||||
|
|
||||||
add_dependencies(qros_robot_dynamics_interface ${${PROJECT_NAME}_EXPORTED_TARGETS})
|
|
||||||
add_dependencies(qros_robot_dynamics_interface ${catkin_EXPORTED_TARGETS})
|
|
||||||
|
|
||||||
|
|
||||||
|
##### 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
|
||||||
Franka::Franka)
|
Franka::Franka)
|
||||||
add_dependencies(qros_effector_driver_franka_hand ${${PROJECT_NAME}_EXPORTED_TARGETS})
|
|
||||||
add_dependencies(qros_effector_driver_franka_hand ${catkin_EXPORTED_TARGETS})
|
|
||||||
|
|
||||||
add_library(sas_robot_driver_coppelia src/coppelia/sas_robot_driver_coppelia.cpp)
|
#target_include_directories(qros_effector_driver_franka_hand
|
||||||
target_link_libraries(sas_robot_driver_coppelia
|
# PUBLIC
|
||||||
dqrobotics
|
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/interface>
|
||||||
dqrobotics-interface-json11
|
# $<INSTALL_INTERFACE:include/interface>)
|
||||||
dqrobotics-interface-vrep)
|
|
||||||
|
|
||||||
add_dependencies(sas_robot_driver_franka ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
##### qros hand effector driver end #####
|
||||||
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/sas_robot_driver_franka/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
|
|
||||||
)
|
|
||||||
add_dependencies(_qros_robot_dynamic ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
|
||||||
|
|
||||||
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_dynamics_py 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_dynamics_py
|
||||||
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_dynamics_py PRIVATE IS_SAS_PYTHON_BUILD)
|
||||||
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
# https://github.com/pybind/pybind11/issues/387
|
||||||
)
|
target_link_libraries(_qros_franka_robot_dynamics_py PRIVATE ${PROJECT_NAME}_robot_dynamics -ldqrobotics)
|
||||||
|
|
||||||
install(TARGETS sas_robot_driver_franka_hand_node
|
install(TARGETS _qros_franka_robot_dynamics_py
|
||||||
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
DESTINATION "${PYTHON_INSTALL_DIR}/${PROJECT_NAME}"
|
||||||
)
|
)
|
||||||
|
##END## PYBIND11 LIBRARY ROBOT_DYNAMICS #####
|
||||||
|
|
||||||
install(TARGETS qros_robot_dynamics_provider
|
|
||||||
DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
|
||||||
)
|
|
||||||
|
|
||||||
install(TARGETS qros_robot_dynamics_interface
|
install(
|
||||||
DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
DIRECTORY include/
|
||||||
)
|
DESTINATION include
|
||||||
|
|
||||||
## Mark cpp header files for installation
|
|
||||||
install(DIRECTORY include/${PROJECT_NAME}/
|
|
||||||
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
|
|
||||||
FILES_MATCHING PATTERN "*.h"
|
|
||||||
# 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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,23 +38,22 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <dqrobotics/DQ.h>
|
#include <dqrobotics/DQ.h>
|
||||||
#include <sas_robot_driver/sas_robot_driver.h>
|
#include <sas_core/sas_clock.hpp>
|
||||||
#include <sas_clock/sas_clock.h>
|
|
||||||
// #include <dqrobotics/interfaces/vrep/DQ_VrepRobot.h>
|
// #include <dqrobotics/interfaces/vrep/DQ_VrepRobot.h>
|
||||||
#include <dqrobotics/interfaces/vrep/DQ_VrepInterface.h>
|
#include <dqrobotics/interfaces/vrep/DQ_VrepInterface.h>
|
||||||
#include <dqrobotics/interfaces/json11/DQ_JsonReader.h>
|
#include <dqrobotics/interfaces/json11/DQ_JsonReader.h>
|
||||||
// #include <dqrobotics/robot_modeling/DQ_SerialManipulatorDH.h>
|
// #include <dqrobotics/robot_modeling/DQ_SerialManipulatorDH.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <sas_robot_driver/sas_robot_driver_interface.h>
|
#include <sas_robot_driver/sas_robot_driver_server.hpp>
|
||||||
#include <sas_robot_driver/sas_robot_driver_provider.h>
|
#include <sas_robot_driver/sas_robot_driver_client.hpp>
|
||||||
|
|
||||||
#define VIRTUAL_ROBOT_SIMULATION_SAMPLING_TIME_NSEC 2000000 // 2ms, 500Hz
|
#define VIRTUAL_ROBOT_SIMULATION_SAMPLING_TIME_SEC 0.002 // 2ms, 500Hz
|
||||||
#define REAL_ROBOT_INTERFACE_INIT_TIMEOUT_COUNT 500
|
#define REAL_ROBOT_INTERFACE_INIT_TIMEOUT_COUNT 500
|
||||||
using namespace DQ_robotics;
|
using namespace DQ_robotics;
|
||||||
using namespace Eigen;
|
using namespace Eigen;
|
||||||
|
|
||||||
namespace sas
|
namespace qros
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@@ -62,7 +61,7 @@ namespace sas
|
|||||||
struct RobotDriverCoppeliaConfiguration
|
struct RobotDriverCoppeliaConfiguration
|
||||||
{
|
{
|
||||||
|
|
||||||
int thread_sampling_time_nsec; // frontend vrep update rate
|
double thread_sampling_time_sec; // frontend vrep update rate
|
||||||
int vrep_port;
|
int vrep_port;
|
||||||
std::string vrep_ip;
|
std::string vrep_ip;
|
||||||
std::vector<std::string> vrep_joint_names;
|
std::vector<std::string> vrep_joint_names;
|
||||||
@@ -84,15 +83,16 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
RobotDriverCoppeliaConfiguration configuration_;
|
RobotDriverCoppeliaConfiguration configuration_;
|
||||||
|
std::shared_ptr<Node> node_sptr_;
|
||||||
|
|
||||||
Clock clock_;
|
sas::Clock clock_;
|
||||||
std::atomic_bool* break_loops_;
|
std::atomic_bool* break_loops_;
|
||||||
bool _should_shutdown() const {return (*break_loops_);}
|
bool _should_shutdown() const {return (*break_loops_);}
|
||||||
ControlMode robot_mode_;
|
ControlMode robot_mode_;
|
||||||
|
|
||||||
std::shared_ptr<DQ_VrepInterface> vi_;
|
std::shared_ptr<DQ_VrepInterface> vi_;
|
||||||
std::shared_ptr<sas::RobotDriverInterface> real_robot_interface_ = nullptr;
|
std::shared_ptr<sas::RobotDriverClient> real_robot_interface_ = nullptr;
|
||||||
std::shared_ptr<sas::RobotDriverProvider> robot_provider_ = nullptr;
|
std::shared_ptr<sas::RobotDriverServer> robot_provider_ = nullptr;
|
||||||
|
|
||||||
// backend thread for simulaton
|
// backend thread for simulaton
|
||||||
/**
|
/**
|
||||||
@@ -123,7 +123,7 @@ public:
|
|||||||
RobotDriverCoppelia()=delete;
|
RobotDriverCoppelia()=delete;
|
||||||
~RobotDriverCoppelia();
|
~RobotDriverCoppelia();
|
||||||
|
|
||||||
RobotDriverCoppelia(ros::NodeHandle nh, const RobotDriverCoppeliaConfiguration& configuration, std::atomic_bool* break_loops);
|
RobotDriverCoppelia(const std::shared_ptr<Node> &node_sptr, const RobotDriverCoppeliaConfiguration& configuration, std::atomic_bool* break_loops);
|
||||||
|
|
||||||
int start_control_loop(); // public entry point
|
int start_control_loop(); // public entry point
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -38,22 +38,30 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <franka/exception.h>
|
|
||||||
// #define BLOCK_READ_IN_USED
|
// #define BLOCK_READ_IN_USED
|
||||||
// #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 <sas_robot_driver_franka/Grasp.h>
|
|
||||||
#include <sas_robot_driver_franka/Move.h>
|
|
||||||
#include <sas_robot_driver_franka/GripperState.h>
|
|
||||||
|
|
||||||
|
#include <rclcpp/service.hpp>
|
||||||
|
#include <rclcpp/rclcpp.hpp>
|
||||||
|
|
||||||
|
#ifdef IN_TESTING
|
||||||
|
#include "local/srv/grasp.hpp"
|
||||||
|
#include "local/srv/move.hpp"
|
||||||
|
#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
|
||||||
|
|
||||||
|
|
||||||
// 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 {
|
||||||
@@ -61,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;
|
||||||
@@ -72,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_;
|
||||||
|
|
||||||
@@ -85,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;
|
||||||
@@ -104,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();
|
||||||
@@ -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;
|
||||||
@@ -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_;}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -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_;}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,18 +40,16 @@
|
|||||||
|
|
||||||
#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 <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_provider.h>
|
#include <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_server.hpp>
|
||||||
#include <sas_clock/sas_clock.h>
|
|
||||||
#include <dqrobotics/utils/DQ_Math.h>
|
|
||||||
#include <ros/this_node.h>
|
|
||||||
#include <rosconsole/macros_generated.h>
|
|
||||||
|
|
||||||
using namespace DQ_robotics;
|
using namespace DQ_robotics;
|
||||||
using namespace Eigen;
|
using namespace Eigen;
|
||||||
|
|
||||||
|
struct RobotInterfaceFranka::FrankaInterfaceConfiguration; // Forward declaration
|
||||||
|
|
||||||
namespace sas
|
namespace sas
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -63,18 +61,19 @@ struct RobotDriverFrankaConfiguration
|
|||||||
double speed;
|
double speed;
|
||||||
RobotInterfaceFranka::FrankaInterfaceConfiguration interface_configuration;
|
RobotInterfaceFranka::FrankaInterfaceConfiguration interface_configuration;
|
||||||
DQ robot_reference_frame = DQ(0);
|
DQ robot_reference_frame = DQ(0);
|
||||||
bool automatic_error_recovery = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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_;
|
||||||
@@ -101,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
|
||||||
);
|
);
|
||||||
45
launch/sas_robot_driver_franka_example.py
Normal file
45
launch/sas_robot_driver_franka_example.py
Normal 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"
|
||||||
|
),
|
||||||
|
|
||||||
|
])
|
||||||
24
launch/sas_robot_driver_franka_hand_example.py
Normal file
24
launch/sas_robot_driver_franka_hand_example.py
Normal 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"
|
||||||
|
),
|
||||||
|
|
||||||
|
])
|
||||||
27
launch/sas_robot_driver_franka_simulation_example.py
Normal file
27
launch/sas_robot_driver_franka_simulation_example.py
Normal 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"
|
||||||
|
),
|
||||||
|
|
||||||
|
])
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
float32 width
|
|
||||||
float32 max_width
|
|
||||||
bool is_grasped
|
|
||||||
uint16 temperature
|
|
||||||
uint64 duration_ms
|
|
||||||
100
package.xml
100
package.xml
@@ -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>
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include "qspinbox.h"
|
#include "qspinbox.h"
|
||||||
#include <sas_robot_driver_franka/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; }
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
import rospy
|
"""
|
||||||
from sas_robot_driver_franka.srv import Move, MoveRequest, MoveResponse, Grasp, GraspRequest, GraspResponse
|
"""
|
||||||
from sas_robot_driver_franka.msg import GripperState
|
from typing import Union
|
||||||
|
|
||||||
|
from sas_robot_driver_franka._qros_franka_robot_dynamics_py import RobotDynamicsClient, RobotDynamicsServer
|
||||||
|
|
||||||
|
import rclpy
|
||||||
|
from rclpy.node import Node
|
||||||
|
from rclpy.client import Client
|
||||||
|
from sas_common import rclcpp_init, rclcpp_Node, rclcpp_spin_some, rclcpp_shutdown
|
||||||
|
from sas_robot_driver_franka_interfaces.srv import Move, Grasp
|
||||||
|
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,36 +26,43 @@ 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, 10)
|
||||||
|
|
||||||
self.result_queue = Queue()
|
self.service_future: Union[rclpy.Future, None] = None
|
||||||
|
|
||||||
# gripper state
|
# gripper state
|
||||||
self.state_width = None
|
self.state_width = None
|
||||||
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 _is_service_ready(self, service):
|
def _default_spin_handler(self):
|
||||||
|
rclpy.spin_once(self.node)
|
||||||
|
|
||||||
|
def _is_service_ready(self, service: Client):
|
||||||
try:
|
try:
|
||||||
rospy.wait_for_service(service, timeout=0.1)
|
# self.node.get_logger().info("Waiting for service: " + service.service_name)
|
||||||
return True
|
ret = service.wait_for_service(timeout_sec=0.1)
|
||||||
except rospy.ROSException:
|
return ret
|
||||||
|
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
|
||||||
|
|
||||||
@@ -64,7 +81,7 @@ class FrankaGripperInterface:
|
|||||||
"""
|
"""
|
||||||
if self.is_busy():
|
if self.is_busy():
|
||||||
raise Exception("Gripper is already moving or grasping, please wait until the previous action is finished")
|
raise Exception("Gripper is already moving or grasping, please wait until the previous action is finished")
|
||||||
threading.Thread(target=self._move, args=(width, speed)).start()
|
self._move(width, speed)
|
||||||
|
|
||||||
def grasp(self, width, force=0, speed=0, epsilon_inner=0, epsilon_outer=0):
|
def grasp(self, width, force=0, speed=0, epsilon_inner=0, epsilon_outer=0):
|
||||||
"""
|
"""
|
||||||
@@ -78,7 +95,7 @@ class FrankaGripperInterface:
|
|||||||
"""
|
"""
|
||||||
if self.is_busy():
|
if self.is_busy():
|
||||||
raise Exception("Gripper is already moving or grasping, please wait until the previous action is finished")
|
raise Exception("Gripper is already moving or grasping, please wait until the previous action is finished")
|
||||||
threading.Thread(target=self._grasp, args=(width, force, speed, epsilon_inner, epsilon_outer)).start()
|
self._grasp(width, force, speed, epsilon_inner, epsilon_outer)
|
||||||
|
|
||||||
def get_max_width(self):
|
def get_max_width(self):
|
||||||
""" Get the maximum width of the gripper """
|
""" Get the maximum width of the gripper """
|
||||||
@@ -114,15 +131,17 @@ class FrankaGripperInterface:
|
|||||||
|
|
||||||
def is_busy(self):
|
def is_busy(self):
|
||||||
""" Check if the gripper is currently moving or grasping """
|
""" Check if the gripper is currently moving or grasping """
|
||||||
return self._moving or self._grasping
|
return self._moving or self._grasping or self.service_future is not None
|
||||||
|
|
||||||
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.service_future is not None:
|
||||||
|
if self.service_future.done():
|
||||||
|
return True
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
@@ -132,11 +151,19 @@ class FrankaGripperInterface:
|
|||||||
Get the result of the last action
|
Get the result of the last action
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
if not self.result_queue.empty():
|
if self.service_future is not None:
|
||||||
response = self.result_queue.get()
|
if self.service_future.done():
|
||||||
self._moving = False
|
response = self.service_future.result()
|
||||||
self._grasping = False
|
if isinstance(response, Move.Response):
|
||||||
return response.success
|
self._moving = False
|
||||||
|
elif isinstance(response, Grasp.Response):
|
||||||
|
self._grasping = False
|
||||||
|
else:
|
||||||
|
raise Exception("Invalid response type")
|
||||||
|
self.service_future = None
|
||||||
|
return response.success
|
||||||
|
else:
|
||||||
|
raise Exception("No result available")
|
||||||
else:
|
else:
|
||||||
raise Exception("No result available")
|
raise Exception("No result available")
|
||||||
|
|
||||||
@@ -147,36 +174,33 @@ class FrankaGripperInterface:
|
|||||||
"""
|
"""
|
||||||
if not self.is_enabled():
|
if not self.is_enabled():
|
||||||
raise Exception("Gripper is not enabled")
|
raise Exception("Gripper is not enabled")
|
||||||
if not self._moving and not self._grasping:
|
if not self.is_busy():
|
||||||
raise Exception("Gripper is not moving or grasping")
|
return
|
||||||
while self._moving or self._grasping:
|
while not self.is_done():
|
||||||
rospy.sleep(0.1)
|
self.spin_handler()
|
||||||
if not self.result_queue.empty():
|
time.sleep(0.01)
|
||||||
response = self.result_queue.get()
|
|
||||||
if isinstance(response, MoveResponse):
|
|
||||||
self._moving = False
|
|
||||||
elif isinstance(response, GraspResponse):
|
|
||||||
self._grasping = False
|
|
||||||
else:
|
|
||||||
raise Exception("Invalid response type")
|
|
||||||
break
|
|
||||||
return response.success
|
|
||||||
|
|
||||||
def _move(self, width, speed):
|
def _move(self, width, speed):
|
||||||
self._moving = True
|
self._moving = True
|
||||||
request = MoveRequest()
|
# self.node.get_logger().info("Moving gripper to width: " + str(width) + " speed: " + str(speed))
|
||||||
request.width = width
|
request = Move.Request()
|
||||||
request.speed = speed
|
request.width = float(width)
|
||||||
response = self.move_service(request)
|
request.speed = float(speed)
|
||||||
self.result_queue.put(response)
|
# self.node.get_logger().info("Calling move service")
|
||||||
|
self.service_future = self.move_service.call_async(request)
|
||||||
|
|
||||||
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()
|
# self.node.get_logger().info("Grasping object at width: " + str(width) + " force: " + str(force) + " speed: " + str(speed))
|
||||||
request.width = width
|
request = Grasp.Request()
|
||||||
request.force = force
|
request.width = float(width)
|
||||||
request.speed = speed
|
request.force = float(force)
|
||||||
request.epsilon_inner = epsilon_inner
|
request.speed = float(speed)
|
||||||
request.epsilon_outer = epsilon_outer
|
request.epsilon_inner = float(epsilon_inner)
|
||||||
response = self.grasp_service(request)
|
request.epsilon_outer = float(epsilon_outer)
|
||||||
self.result_queue.put(response)
|
# self.node.get_logger().info("Calling grasp service")
|
||||||
|
self.service_future = self.grasp_service.call_async(request)
|
||||||
|
|
||||||
|
|
||||||
|
def set_spin_handler(self, spin_handler):
|
||||||
|
self.spin_handler = spin_handler
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
12
setup.py
12
setup.py
@@ -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)
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "sas_robot_driver_coppelia.h"
|
#include <sas_robot_driver_franka/coppelia/sas_robot_driver_coppelia.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace sas
|
namespace qros
|
||||||
{
|
{
|
||||||
|
|
||||||
RobotDriverCoppelia::~RobotDriverCoppelia() {
|
RobotDriverCoppelia::~RobotDriverCoppelia() {
|
||||||
@@ -9,9 +9,10 @@ RobotDriverCoppelia::~RobotDriverCoppelia() {
|
|||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
RobotDriverCoppelia::RobotDriverCoppelia(ros::NodeHandle nh, 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):
|
||||||
configuration_(configuration),
|
configuration_(configuration),
|
||||||
clock_(configuration.thread_sampling_time_nsec),
|
node_sptr_(node_sptr),
|
||||||
|
clock_(configuration.thread_sampling_time_sec),
|
||||||
break_loops_(break_loops),
|
break_loops_(break_loops),
|
||||||
robot_mode_(ControlMode::Position),
|
robot_mode_(ControlMode::Position),
|
||||||
vi_(std::make_shared<DQ_VrepInterface>())
|
vi_(std::make_shared<DQ_VrepInterface>())
|
||||||
@@ -21,11 +22,11 @@ RobotDriverCoppelia::RobotDriverCoppelia(ros::NodeHandle nh, const RobotDriverCo
|
|||||||
joint_limits_ = {smdh.get_lower_q_limit(),smdh.get_upper_q_limit()};
|
joint_limits_ = {smdh.get_lower_q_limit(),smdh.get_upper_q_limit()};
|
||||||
if(configuration_.using_real_robot)
|
if(configuration_.using_real_robot)
|
||||||
{
|
{
|
||||||
ROS_INFO_STREAM("[" + ros::this_node::getName() + "]::Using real robot, Instantiating robot interface to real driver.");
|
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<RobotDriverInterface>(nh, configuration_.robot_topic_prefix);
|
real_robot_interface_ = std::make_shared<sas::RobotDriverClient>(node_sptr_, configuration_.robot_topic_prefix);
|
||||||
}else{
|
}else{
|
||||||
ROS_INFO_STREAM("[" + ros::this_node::getName() + "]::Using simulation robot, simulation mode is set to "+ configuration_.robot_mode);
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Using simulation robot, simulation mode is set to "+ configuration_.robot_mode);
|
||||||
robot_provider_ = std::make_shared<RobotDriverProvider>(nh, configuration_.robot_topic_prefix);
|
robot_provider_ = std::make_shared<sas::RobotDriverServer>(node_sptr_, configuration_.robot_topic_prefix);
|
||||||
std::string _mode_upper = configuration_.robot_mode;
|
std::string _mode_upper = configuration_.robot_mode;
|
||||||
std::transform(_mode_upper.begin(), _mode_upper.end(), _mode_upper.begin(), ::toupper);
|
std::transform(_mode_upper.begin(), _mode_upper.end(), _mode_upper.begin(), ::toupper);
|
||||||
if(_mode_upper == "POSITIONCONTROL"){
|
if(_mode_upper == "POSITIONCONTROL"){
|
||||||
@@ -33,7 +34,7 @@ RobotDriverCoppelia::RobotDriverCoppelia(ros::NodeHandle nh, const RobotDriverCo
|
|||||||
}else if(_mode_upper == "VELOCITYCONTROL"){
|
}else if(_mode_upper == "VELOCITYCONTROL"){
|
||||||
robot_mode_ = ControlMode::Velocity;
|
robot_mode_ = ControlMode::Velocity;
|
||||||
}else{
|
}else{
|
||||||
throw std::invalid_argument("[" + ros::this_node::getName() + "]::Robot mode must be either 'position' or 'velocity'");
|
throw std::invalid_argument("[" + std::string(node_sptr_->get_name()) + "]::Robot mode must be either 'position' or 'velocity'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,11 +60,11 @@ void RobotDriverCoppelia::_update_vrep_velocity(const VectorXd & joint_velocity)
|
|||||||
|
|
||||||
void RobotDriverCoppelia::_start_control_loop(){
|
void RobotDriverCoppelia::_start_control_loop(){
|
||||||
clock_.init();
|
clock_.init();
|
||||||
ROS_INFO_STREAM("[" + ros::this_node::getName() + "]::Starting control loop...");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Starting control loop...");
|
||||||
while(!_should_shutdown()){
|
while(!_should_shutdown()){
|
||||||
clock_.update_and_sleep();
|
clock_.update_and_sleep();
|
||||||
ros::spinOnce();
|
rclcpp::spin_some(node_sptr_);
|
||||||
if(!ros::ok()){break_loops_->store(true);}
|
if(!rclcpp::ok()){break_loops_->store(true);}
|
||||||
if(configuration_.using_real_robot){
|
if(configuration_.using_real_robot){
|
||||||
// real_robot_interface_
|
// real_robot_interface_
|
||||||
auto joint_position = real_robot_interface_->get_joint_positions();
|
auto joint_position = real_robot_interface_->get_joint_positions();
|
||||||
@@ -82,7 +83,7 @@ void RobotDriverCoppelia::_start_control_loop(){
|
|||||||
// try{_update_vrep_velocity(simulated_joint_velocities_);}catch (...){}
|
// try{_update_vrep_velocity(simulated_joint_velocities_);}catch (...){}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
ROS_DEBUG_STREAM("[" + ros::this_node::getName() + "]::Velocity control is not enabled.");
|
RCLCPP_DEBUG_STREAM(node_sptr_->get_logger(), "::Velocity control is not enabled.");
|
||||||
}
|
}
|
||||||
target_joint_positions = simulated_joint_positions_;
|
target_joint_positions = simulated_joint_positions_;
|
||||||
}else{
|
}else{
|
||||||
@@ -103,29 +104,29 @@ void RobotDriverCoppelia::_start_control_loop(){
|
|||||||
|
|
||||||
int RobotDriverCoppelia::start_control_loop(){
|
int RobotDriverCoppelia::start_control_loop(){
|
||||||
try{
|
try{
|
||||||
ROS_INFO_STREAM(ros::this_node::getName() << "::Waiting to connect with coppelia...");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Waiting to connect with coppelia...");
|
||||||
connect();
|
connect();
|
||||||
ROS_INFO_STREAM(ros::this_node::getName() << "::Connected to coppelia.");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Connected to coppelia.");
|
||||||
ROS_INFO_STREAM(ros::this_node::getName() << "::Initializing...");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Initializing...");
|
||||||
initialize();
|
initialize();
|
||||||
ROS_INFO_STREAM(ros::this_node::getName() << "::initialized.");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::initialized.");
|
||||||
|
|
||||||
_start_control_loop();
|
_start_control_loop();
|
||||||
}
|
}
|
||||||
catch(const std::exception& e)
|
catch(const std::exception& e)
|
||||||
{
|
{
|
||||||
ROS_WARN_STREAM(ros::this_node::getName() + "::Error or exception caught::" << e.what());
|
RCLCPP_WARN_STREAM(node_sptr_->get_logger(), "::Error or exception caught::" << e.what());
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
ROS_WARN_STREAM(ros::this_node::getName() + "::Unexpected error or exception caught");
|
RCLCPP_WARN_STREAM(node_sptr_->get_logger(), "::Unexpected error or exception caught");
|
||||||
}
|
}
|
||||||
ROS_INFO_STREAM(ros::this_node::getName() << "::Deinitializing...");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Deinitializing...");
|
||||||
deinitialize();
|
deinitialize();
|
||||||
ROS_INFO_STREAM(ros::this_node::getName() << "::deinitialized.");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::deinitialized.");
|
||||||
ROS_INFO_STREAM(ros::this_node::getName() << "::Disconnecting from coppelia...");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Disconnecting from coppelia...");
|
||||||
disconnect();
|
disconnect();
|
||||||
ROS_INFO_STREAM(ros::this_node::getName() << "::Disconnected from coppelia.");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::Disconnected from coppelia.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -136,7 +137,7 @@ void RobotDriverCoppelia::connect(){
|
|||||||
if(!ret){
|
if(!ret){
|
||||||
throw std::runtime_error("[RobotDriverCoppelia]::connect::Could not connect to Vrep");
|
throw std::runtime_error("[RobotDriverCoppelia]::connect::Could not connect to Vrep");
|
||||||
}
|
}
|
||||||
ROS_INFO_STREAM("[" + ros::this_node::getName() + "]::[RobotDriverCoppelia]::connect::Connected to Vrep");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::connect::Connected to Vrep");
|
||||||
}
|
}
|
||||||
void RobotDriverCoppelia::disconnect(){
|
void RobotDriverCoppelia::disconnect(){
|
||||||
vi_->disconnect_all();
|
vi_->disconnect_all();
|
||||||
@@ -145,27 +146,29 @@ void RobotDriverCoppelia::disconnect(){
|
|||||||
void RobotDriverCoppelia::initialize(){
|
void RobotDriverCoppelia::initialize(){
|
||||||
if(configuration_.using_real_robot)
|
if(configuration_.using_real_robot)
|
||||||
{
|
{
|
||||||
ROS_INFO_STREAM("[" + ros::this_node::getName() +"]::[RobotDriverCoppelia]::initialize::Waiting for real robot interface to initialize...");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::initialize::Waiting for real robot interface to initialize...");
|
||||||
ros::spinOnce();
|
rclcpp::spin_some(node_sptr_);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (!real_robot_interface_->is_enabled()) {
|
while (!real_robot_interface_->is_enabled(sas::RobotDriver::Functionality::PositionControl)) {
|
||||||
ros::spinOnce();
|
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));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
rclcpp::spin_some(node_sptr_);
|
||||||
count++;
|
count++;
|
||||||
if(count > REAL_ROBOT_INTERFACE_INIT_TIMEOUT_COUNT){
|
if(count > REAL_ROBOT_INTERFACE_INIT_TIMEOUT_COUNT){
|
||||||
ROS_ERROR_STREAM("[" + ros::this_node::getName() +"]::[RobotDriverCoppelia]::initialize::Real robot interface not initialized. Exiting on TIMEOUT...");
|
RCLCPP_ERROR_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::initialize::Real robot interface not initialized. Exiting on TIMEOUT...");
|
||||||
throw std::runtime_error("[" + ros::this_node::getName() +"]::[RobotDriverCoppelia]::initialize::Real robot interface not initialized.");
|
throw std::runtime_error("[" + std::string(node_sptr_->get_name()) +"]::[RobotDriverCoppelia]::initialize::Real robot interface not initialized.");
|
||||||
}
|
}
|
||||||
if(!ros::ok()) {
|
if(!rclcpp::ok()) {
|
||||||
ROS_WARN_STREAM("[" + ros::this_node::getName() +"]::[RobotDriverCoppelia]::initialize::ROS shutdown recieved. Exiting...");
|
RCLCPP_WARN_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::initialize::ROS shutdown received. Exiting...");
|
||||||
throw std::runtime_error("[" + ros::this_node::getName() +"]::[RobotDriverCoppelia]::initialize::ROS shutdown recieved, not OK.");
|
throw std::runtime_error("[" + std::string(node_sptr_->get_name()) +"]::[RobotDriverCoppelia]::initialize::ROS shutdown received, not OK.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ROS_INFO_STREAM("[" + ros::this_node::getName() +"]::[RobotDriverCoppelia]::initialize::Real robot interface initialized.");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::initialize::Real robot interface initialized.");
|
||||||
joint_limits_ = real_robot_interface_->get_joint_limits();
|
joint_limits_ = real_robot_interface_->get_joint_limits();
|
||||||
_update_vrep_position(real_robot_interface_->get_joint_positions(), true);
|
_update_vrep_position(real_robot_interface_->get_joint_positions(), true);
|
||||||
}else{
|
}else{
|
||||||
ROS_INFO_STREAM("[" + ros::this_node::getName() +"]::[RobotDriverCoppelia]::initialize::Simulation mode.");
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::initialize::Simulation mode.");
|
||||||
// initialization information for robot driver provider
|
// initialization information for robot driver provider
|
||||||
/**
|
/**
|
||||||
* TODO: check for making sure real robot is not actually connected
|
* TODO: check for making sure real robot is not actually connected
|
||||||
@@ -206,13 +209,12 @@ void RobotDriverCoppelia::_velocity_control_simulation_thread_main(){
|
|||||||
*/
|
*/
|
||||||
simulation_thread_started_ = true;
|
simulation_thread_started_ = true;
|
||||||
try{
|
try{
|
||||||
ROS_INFO_STREAM("[" + ros::this_node::getName() +
|
RCLCPP_INFO_STREAM(node_sptr_->get_logger(), "::RobotDriverCoppelia]::[_velocity_control_simulation_thread_main]::Simulation thread started.");
|
||||||
"]::[RobotDriverCoppelia]::[_velocity_control_simulation_thread_main]::Simulation thread started.");
|
sas::Clock clock = sas::Clock(VIRTUAL_ROBOT_SIMULATION_SAMPLING_TIME_SEC);
|
||||||
sas::Clock clock = sas::Clock(VIRTUAL_ROBOT_SIMULATION_SAMPLING_TIME_NSEC);
|
double tau = VIRTUAL_ROBOT_SIMULATION_SAMPLING_TIME_SEC;
|
||||||
double tau = static_cast<double>(VIRTUAL_ROBOT_SIMULATION_SAMPLING_TIME_NSEC) * 1e-9;
|
|
||||||
auto current_joint_positions = simulated_joint_positions_;
|
auto current_joint_positions = simulated_joint_positions_;
|
||||||
clock.init();
|
clock.init();
|
||||||
while (!(*break_loops_) && ros::ok()) {
|
while (!(*break_loops_) && rclcpp::ok()) {
|
||||||
|
|
||||||
current_joint_positions += tau * simulated_joint_velocities_; // no dynamic model
|
current_joint_positions += tau * simulated_joint_velocities_; // no dynamic model
|
||||||
// cap joint limit
|
// cap joint limit
|
||||||
@@ -230,12 +232,13 @@ void RobotDriverCoppelia::_velocity_control_simulation_thread_main(){
|
|||||||
clock.update_and_sleep();
|
clock.update_and_sleep();
|
||||||
}
|
}
|
||||||
}catch(std::exception &e){
|
}catch(std::exception &e){
|
||||||
ROS_ERROR_STREAM("[" + ros::this_node::getName() + "]::[RobotDriverCoppelia]::[_velocity_control_simulation_thread_main]::Exception::" + e.what());
|
RCLCPP_ERROR_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::[_velocity_control_simulation_thread_main]::Exception::" << e.what());
|
||||||
simulation_thread_started_ = false;
|
simulation_thread_started_ = false;
|
||||||
}catch(...){
|
}catch(...){
|
||||||
ROS_ERROR_STREAM("[" + ros::this_node::getName() + "]::[RobotDriverCoppelia]::[_velocity_control_simulation_thread_main]::Exception::Unknown");
|
RCLCPP_ERROR_STREAM(node_sptr_->get_logger(), "::[RobotDriverCoppelia]::[_velocity_control_simulation_thread_main]::Exception::Unknown");
|
||||||
simulation_thread_started_ = false;
|
simulation_thread_started_ = false;
|
||||||
}
|
}
|
||||||
|
break_loops_->store(true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
#include <sas_common/sas_common.h>
|
#include <sas_common/sas_common.h>
|
||||||
#include <sas_conversions/eigen3_std_conversions.h>
|
#include <sas_conversions/eigen3_std_conversions.h>
|
||||||
#include <sas_robot_driver/sas_robot_driver_ros.h>
|
#include <sas_robot_driver/sas_robot_driver_ros.h>
|
||||||
#include "../../include/sas_robot_driver_franka/sas_robot_driver_franka.h"
|
#include "sas_robot_driver_franka.h"
|
||||||
#include "robot_coppelia_ros_interface.h"
|
#include "robot_coppelia_ros_interface.h"
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
|
|||||||
@@ -27,8 +27,12 @@
|
|||||||
#
|
#
|
||||||
# ################################################################
|
# ################################################################
|
||||||
*/
|
*/
|
||||||
#include "qros_effector_driver_franka_hand.h"
|
#include <sas_robot_driver_franka/interfaces/qros_effector_driver_franka_hand.hpp>
|
||||||
|
|
||||||
|
#include <franka/exception.h>
|
||||||
|
|
||||||
|
using namespace std::placeholders;
|
||||||
|
using namespace sas_robot_driver_franka_interfaces;
|
||||||
|
|
||||||
|
|
||||||
namespace qros
|
namespace qros
|
||||||
@@ -47,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,56 +78,48 @@ namespace qros
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EffectorDriverFrankaHand::start_control_loop()
|
void EffectorDriverFrankaHand::start_control_loop() {
|
||||||
{
|
sas::Clock clock = sas::Clock(configuration_.thread_sampeling_time_s);
|
||||||
sas::Clock clock = sas::Clock(configuration_.thread_sampeling_time_ns);
|
|
||||||
clock.init();
|
clock.init();
|
||||||
ROS_INFO_STREAM(
|
RCLCPP_INFO_STREAM(node_->get_logger(),"[EffectorDriverFrankaHand]::start_control_loop::Starting control loop.");
|
||||||
"["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::start_control_loop::Starting control loop.");
|
RCLCPP_WARN_STREAM(node_->get_logger(),"[EffectorDriverFrankaHand]::Gripper READY.");
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -134,35 +130,40 @@ 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(),"[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);
|
||||||
|
// check status loop with timeout
|
||||||
|
auto time_now = std::chrono::system_clock::now();
|
||||||
|
auto time_out = time_now + std::chrono::seconds(5);
|
||||||
|
while (!status_loop_running_)
|
||||||
|
{
|
||||||
|
if (std::chrono::system_clock::now() > time_out){throw std::runtime_error("[" + std::string(node_->get_name()) + "]::[EffectorDriverFrankaHand]::initialize::Could not start status loop.");}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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())
|
||||||
@@ -176,20 +177,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();
|
||||||
@@ -199,30 +199,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();
|
||||||
@@ -232,48 +231,44 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EffectorDriverFrankaHand::_gripper_status_loop()
|
void EffectorDriverFrankaHand::_gripper_status_loop()
|
||||||
{
|
{
|
||||||
status_loop_running_ = true;
|
sas::Clock clock = sas::Clock(configuration_.thread_sampeling_time_s);
|
||||||
sas::Clock clock = sas::Clock(configuration_.thread_sampeling_time_ns);
|
RCLCPP_INFO_STREAM(node_->get_logger(),"["+ std::string(node_->get_name())+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Starting status loop.");
|
||||||
ROS_INFO_STREAM(
|
|
||||||
"["+ ros::this_node::getName()+"]::[EffectorDriverFrankaHand]::_gripper_status_loop::Starting status loop.")
|
|
||||||
;
|
|
||||||
clock.init();
|
clock.init();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
status_loop_running_ = true;
|
||||||
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();
|
||||||
@@ -283,23 +278,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();
|
||||||
@@ -308,19 +303,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
|
||||||
|
|||||||
@@ -1,4 +1,33 @@
|
|||||||
#include <sas_robot_driver_franka/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"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,10 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <sas_robot_driver_franka/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,
|
||||||
|
|||||||
@@ -30,15 +30,22 @@
|
|||||||
# ################################################################
|
# ################################################################
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sas_robot_driver_franka/sas_robot_driver_franka.h>
|
|
||||||
|
#include <sas_robot_driver_franka/sas_robot_driver_franka.hpp>
|
||||||
|
#include <sas_core/sas_clock.hpp>
|
||||||
|
#include <dqrobotics/utils/DQ_Math.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);
|
||||||
@@ -48,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"))
|
||||||
{
|
{
|
||||||
@@ -86,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -139,12 +145,15 @@ 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(!ros::ok()) {
|
if(!ok()) {
|
||||||
ROS_ERROR_STREAM("["+ros::this_node::getName()+"]::ROS shutdown requested.");
|
RCLCPP_WARN_STREAM(node_->get_logger(),
|
||||||
break_loops_->store(true);
|
"["+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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
102
src/robot_dynamics/qros_robot_dynamics_client.cpp
Normal file
102
src/robot_dynamics/qros_robot_dynamics_client.cpp
Normal 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;
|
||||||
|
}
|
||||||
@@ -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 <sas_robot_driver_franka/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;
|
|
||||||
}
|
|
||||||
@@ -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 <sas_robot_driver_franka/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
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -32,29 +32,29 @@
|
|||||||
#include <pybind11/stl.h>
|
#include <pybind11/stl.h>
|
||||||
#include <pybind11/eigen.h>
|
#include <pybind11/eigen.h>
|
||||||
|
|
||||||
#include <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_provider.h>
|
#include <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_client.hpp>
|
||||||
#include <sas_robot_driver_franka/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_dynamics_py, 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);
|
||||||
|
|
||||||
}
|
}
|
||||||
120
src/robot_dynamics/qros_robot_dynamics_server.cpp
Normal file
120
src/robot_dynamics/qros_robot_dynamics_server.cpp
Normal 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
|
||||||
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,8 @@
|
|||||||
# - 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)
|
# 2. Quentin Lin (qlin1806@g.ecc.u-tokyo.ac.jp)
|
||||||
-Adapted for simplify operation
|
# - Adapted for simplify operation
|
||||||
|
# - porting to ROS2
|
||||||
#
|
#
|
||||||
# ################################################################
|
# ################################################################
|
||||||
*/
|
*/
|
||||||
@@ -38,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 "../../src/coppelia/sas_robot_driver_coppelia.h"
|
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
* SIGNAL HANDLER
|
* SIGNAL HANDLER
|
||||||
@@ -59,46 +59,46 @@ 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("--------------------- Quentin Lin -----------------------------------");
|
|
||||||
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_param(nh,"/thread_sampling_time_nsec",robot_driver_coppelia_configuration.thread_sampling_time_nsec);
|
sas::get_ros_parameter(node,"vrep_ip",robot_driver_coppelia_configuration.vrep_ip);
|
||||||
sas::get_ros_param(nh,"/vrep_ip",robot_driver_coppelia_configuration.vrep_ip);
|
sas::get_ros_parameter(node,"vrep_port",robot_driver_coppelia_configuration.vrep_port);
|
||||||
sas::get_ros_param(nh,"/vrep_port",robot_driver_coppelia_configuration.vrep_port);
|
sas::get_ros_parameter(node,"vrep_joint_names", robot_driver_coppelia_configuration.vrep_joint_names);
|
||||||
sas::get_ros_param(nh,"/vrep_joint_names", robot_driver_coppelia_configuration.vrep_joint_names);
|
sas::get_ros_parameter(node,"vrep_dynamically_enabled", robot_driver_coppelia_configuration.vrep_dynamically_enabled);
|
||||||
sas::get_ros_param(nh,"/vrep_dynamically_enabled", robot_driver_coppelia_configuration.vrep_dynamically_enabled);
|
sas::get_ros_parameter(node,"robot_mode", robot_driver_coppelia_configuration.robot_mode);
|
||||||
sas::get_ros_param(nh,"/robot_mode", robot_driver_coppelia_configuration.robot_mode);
|
sas::get_ros_parameter(node,"using_real_robot", robot_driver_coppelia_configuration.using_real_robot);
|
||||||
sas::get_ros_param(nh,"/using_real_robot", robot_driver_coppelia_configuration.using_real_robot);
|
sas::get_ros_parameter(node,"robot_topic_prefix", robot_driver_coppelia_configuration.robot_topic_prefix);
|
||||||
sas::get_ros_param(nh,"/robot_topic_prefix", robot_driver_coppelia_configuration.robot_topic_prefix);
|
sas::get_ros_parameter(node,"robot_parameter_file_path", robot_driver_coppelia_configuration.robot_parameter_file_path);
|
||||||
sas::get_ros_param(nh,"/robot_parameter_file_path", robot_driver_coppelia_configuration.robot_parameter_file_path);
|
|
||||||
|
|
||||||
// std::vector<double> q_min_vec, q_max_vec;
|
|
||||||
// sas::get_ros_param(nh,"/q_min", q_min_vec);
|
|
||||||
// robot_driver_coppelia_configuration.q_min = sas::std_vector_double_to_vectorxd(q_min_vec);
|
|
||||||
// sas::get_ros_param(nh,"/q_max", q_max_vec);
|
|
||||||
// robot_driver_coppelia_configuration.q_max = sas::std_vector_double_to_vectorxd(q_max_vec);
|
|
||||||
|
|
||||||
|
|
||||||
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(nh, robot_driver_coppelia_configuration,
|
qros::RobotDriverCoppelia robot_driver_coppelia(node, robot_driver_coppelia_configuration,
|
||||||
&kill_this_process);
|
&kill_this_process);
|
||||||
|
|
||||||
return robot_driver_coppelia.start_control_loop();
|
return robot_driver_coppelia.start_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
"""
|
|
||||||
"""
|
|
||||||
from _qros_robot_dynamic import RobotDynamicsInterface, RobotDynamicsProvider
|
|
||||||
from .franka_gripper_interface import FrankaGripperInterface
|
|
||||||
@@ -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 "../../src/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 ¶m_name, T ¶m)
|
void get_optional_parameter(std::shared_ptr<Node> node, const std::string ¶m_name, T ¶m)
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|||||||
@@ -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/sas_robot_driver_franka.h>
|
#include <sas_robot_driver_franka/sas_robot_driver_franka.hpp>
|
||||||
#include <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_provider.h>
|
#include <sas_robot_driver_franka/robot_dynamic/qros_robot_dynamics_server.hpp>
|
||||||
|
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
@@ -74,100 +76,106 @@ 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 {
|
||||||
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);
|
||||||
|
RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Upper torque threshold override and set.");
|
||||||
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 {
|
}catch(...) {
|
||||||
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 {
|
||||||
ROS_INFO_STREAM(ros::this_node::getName()+"::Upper force threshold override and set.");
|
std::vector<double> upper_force_threshold_std_vec;
|
||||||
std::vector<double> upper_torque_threshold_std_vec;
|
sas::get_ros_parameter(node,"upper_force_threshold",upper_force_threshold_std_vec);
|
||||||
sas::get_ros_param(nh,"/upper_force_threshold",upper_torque_threshold_std_vec);
|
RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Upper force threshold override and set.");
|
||||||
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_force_threshold_std_vec);
|
||||||
}else {
|
}catch(...) {
|
||||||
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 torque 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 {
|
||||||
{
|
|
||||||
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.");}
|
}catch(...) {
|
||||||
|
RCLCPP_INFO_STREAM_ONCE(node->get_logger(),"["+node_name+"]::Robot parameter file path not set. Robot Model Unknow.");
|
||||||
if(nh.hasParam(ros::this_node::getName()+"/automatic_error_recovery")) {
|
|
||||||
sas::get_ros_param(nh,"/automatic_error_recovery",robot_driver_franka_configuration.automatic_error_recovery);
|
|
||||||
if(robot_driver_franka_configuration.automatic_error_recovery)
|
|
||||||
{
|
|
||||||
ROS_WARN_STREAM(ros::this_node::getName()+"::Automatic error recovery enabled. STATUS EXPERIMENTAL");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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();
|
||||||
@@ -175,7 +183,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
float32 width
|
|
||||||
float32 speed
|
|
||||||
float32 force
|
|
||||||
float32 epsilon_inner
|
|
||||||
float32 epsilon_outer
|
|
||||||
---
|
|
||||||
bool success
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
float32 width
|
|
||||||
float32 speed
|
|
||||||
---
|
|
||||||
bool success
|
|
||||||
Reference in New Issue
Block a user