diff --git a/Dockerfile b/Dockerfile index e7a82ec..43f59a4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,9 @@ RUN apt-get update && apt-get install -y \ python3-colcon-common-extensions python3-pip \ ros-humble-xacro \ ros-humble-hardware-interface \ - ros-humble-controller-interface + ros-humble-controller-interface \ + ros-humble-joy \ + ros-humble-teleop-twist-joy COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt @@ -32,4 +34,5 @@ RUN echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc ENV PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/ros/humble/bin" # Source the workspace +RUN echo "source install/setup.bash" >> /root/.bashrc CMD ["/bin/bash"] diff --git a/README.md b/README.md index 8b40058..d2f87a2 100644 --- a/README.md +++ b/README.md @@ -28,17 +28,45 @@ To download this repository and all of its included submodules, follow these ste 2. **Starting the Containers** * Navigate to the project directory in your terminal: - ```bash - cd UR-Robotiq - ``` - - * When using the "ur_robotiq.urdf" file first run ```bash - cd /ros2_ws/src/ur_robotiq_description/urdf - ros2 run xacro xacro ur_robotiq.urdf.xacro > ur_robotiq.urdf + cd UR-Robotiq ``` + * Run the following command to start the Docker Compose: ```bash - docker-compose up -d + docker compose up -d ``` - \ No newline at end of file + * Give X11 permission to accept the stream of the container window: + ```bash + xhost + + ``` + * Get the name of the container: + ```bash + docker ps + ``` + * Access the terminal of the docker container + ```bash + docker exec -it /bin/bash + ``` + +## Working with UR + Robotiq +In general you need to start up the UR Robotiq Controller, +here the *robot_ip* has to be defined and if you want to start up the real robot or use fake hardware and if you want to launch rviz! +```bash +ros2 launch ur_robotiq_description ur_robotiq_control.launch.py robot_ip:=aaa.bbb.ccc.ddd use_fake_hardware:= launch_rviz:= +``` + +In addition you can start up the moveit interface: +```bash +ros2 launch ur_robotiq_moveit_config ur_robotiq_moveit.launch.py use_fake_hardware:= +``` + +### use_fake_hardware:=true +Terminal 1.: +```bash +ros2 launch ur_robotiq_description ur_robotiq_control.launch.py robot_ip:=aaa.bbb.ccc.ddd use_fake_hardware:=true launch_rviz:=false +``` +Terminal 2.: +```bash +ros2 launch ur_robotiq_moveit_config ur_robotiq_moveit.launch.py use_fake_hardware:=true +``` diff --git a/docker-compose.yaml b/docker-compose.yaml index e9915b8..0292553 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -13,6 +13,7 @@ services: - DISPLAY=$DISPLAY devices: - /dev/dri:/dev/dri + - /dev/input:/dev/input networks: ros_network: diff --git a/src/ur_robotiq_description/launch/ur_robotiq_control.launch.py b/src/ur_robotiq_description/launch/ur_robotiq_control.launch.py index 61dcfad..e05adf5 100644 --- a/src/ur_robotiq_description/launch/ur_robotiq_control.launch.py +++ b/src/ur_robotiq_description/launch/ur_robotiq_control.launch.py @@ -191,7 +191,11 @@ def launch_setup(context, *args, **kwargs): control_node = Node( package="controller_manager", executable="ros2_control_node", - parameters=[robot_description, update_rate_config_file, initial_joint_controllers], + parameters=[ + robot_description, + update_rate_config_file, + ParameterFile(initial_joint_controllers, allow_substs=True), + ], output="screen", condition=IfCondition(use_fake_hardware), ) @@ -199,7 +203,11 @@ def launch_setup(context, *args, **kwargs): ur_control_node = Node( package="ur_robot_driver", executable="ur_ros2_control_node", - parameters=[robot_description, update_rate_config_file, initial_joint_controllers], + parameters=[ + robot_description, + update_rate_config_file, + ParameterFile(initial_joint_controllers, allow_substs=True), + ], output="screen", condition=UnlessCondition(use_fake_hardware), ) @@ -282,55 +290,58 @@ def launch_setup(context, *args, **kwargs): arguments=["-d", rviz_config_file], ) - joint_state_broadcaster_spawner = Node( - package="controller_manager", - executable="spawner", - arguments=["joint_state_broadcaster", "--controller-manager", "/controller_manager"], - ) + # Spawn controllers + def controller_spawner(name, active=True): + inactive_flags = ["--inactive"] if not active else [] + return Node( + package="controller_manager", + executable="spawner", + arguments=[ + name, + "--controller-manager", + "/controller_manager", + "--controller-manager-timeout", + controller_spawner_timeout, + ] + + inactive_flags, + ) - io_and_status_controller_spawner = Node( - package="controller_manager", - executable="spawner", - arguments=["io_and_status_controller", "-c", "/controller_manager"], - ) + controller_spawner_names = [ + "joint_state_broadcaster", + "io_and_status_controller", + "speed_scaling_state_broadcaster", + "force_torque_sensor_broadcaster", + ] + controller_spawner_inactive_names = ["forward_position_controller"] - speed_scaling_state_broadcaster_spawner = Node( - package="controller_manager", - executable="spawner", - arguments=[ - "speed_scaling_state_broadcaster", - "--controller-manager", - "/controller_manager", - ], - ) - - force_torque_sensor_broadcaster_spawner = Node( - package="controller_manager", - executable="spawner", - arguments=[ - "force_torque_sensor_broadcaster", - "--controller-manager", - "/controller_manager", - ], - ) - - forward_position_controller_spawner_stopped = Node( - package="controller_manager", - executable="spawner", - arguments=["forward_position_controller", "-c", "/controller_manager", "--stopped"], - ) + controller_spawners = [controller_spawner(name) for name in controller_spawner_names] + [ + controller_spawner(name, active=False) for name in controller_spawner_inactive_names + ] # There may be other controllers of the joints, but this is the initially-started one initial_joint_controller_spawner_started = Node( package="controller_manager", executable="spawner", - arguments=[initial_joint_controller, "-c", "/controller_manager"], + arguments=[ + initial_joint_controller, + "-c", + "/controller_manager", + "--controller-manager-timeout", + controller_spawner_timeout, + ], condition=IfCondition(activate_joint_controller), ) initial_joint_controller_spawner_stopped = Node( package="controller_manager", executable="spawner", - arguments=[initial_joint_controller, "-c", "/controller_manager", "--stopped"], + arguments=[ + initial_joint_controller, + "-c", + "/controller_manager", + "--controller-manager-timeout", + controller_spawner_timeout, + "--inactive", + ], condition=UnlessCondition(activate_joint_controller), ) @@ -344,14 +355,9 @@ def launch_setup(context, *args, **kwargs): controller_stopper_node, robot_state_publisher_node, rviz_node, - joint_state_broadcaster_spawner, - io_and_status_controller_spawner, - speed_scaling_state_broadcaster_spawner, - force_torque_sensor_broadcaster_spawner, - forward_position_controller_spawner_stopped, initial_joint_controller_spawner_stopped, initial_joint_controller_spawner_started, - ] + ] + controller_spawners return nodes_to_start diff --git a/src/ur_robotiq_servo/package.xml b/src/ur_robotiq_servo/package.xml new file mode 100644 index 0000000..f936ee1 --- /dev/null +++ b/src/ur_robotiq_servo/package.xml @@ -0,0 +1,25 @@ + + + + ur_robotiq_servo + 0.0.0 + TODO: Package description + niko + TODO: License declaration + + rclpy + sensor_msgs + geometry_msgs + std_msgs + joy + moveit_servo + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/src/ur_robotiq_servo/resource/ur_robotiq_servo b/src/ur_robotiq_servo/resource/ur_robotiq_servo new file mode 100644 index 0000000..e69de29 diff --git a/src/ur_robotiq_servo/setup.cfg b/src/ur_robotiq_servo/setup.cfg new file mode 100644 index 0000000..722d8a6 --- /dev/null +++ b/src/ur_robotiq_servo/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script_dir=$base/lib/ur_robotiq_servo +[install] +install_scripts=$base/lib/ur_robotiq_servo diff --git a/src/ur_robotiq_servo/setup.py b/src/ur_robotiq_servo/setup.py new file mode 100644 index 0000000..1114fd8 --- /dev/null +++ b/src/ur_robotiq_servo/setup.py @@ -0,0 +1,25 @@ +from setuptools import find_packages, setup + +package_name = 'ur_robotiq_servo' + +setup( + name=package_name, + version='0.0.0', + packages=find_packages(exclude=['test']), + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='niko', + maintainer_email='nikolaus.feith@unileoben.ac.at', + description='TODO: Package description', + license='TODO: License declaration', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + ], + }, +) diff --git a/src/ur_robotiq_servo/test/test_copyright.py b/src/ur_robotiq_servo/test/test_copyright.py new file mode 100644 index 0000000..97a3919 --- /dev/null +++ b/src/ur_robotiq_servo/test/test_copyright.py @@ -0,0 +1,25 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_copyright.main import main +import pytest + + +# Remove the `skip` decorator once the source file(s) have a copyright header +@pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') +@pytest.mark.copyright +@pytest.mark.linter +def test_copyright(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found errors' diff --git a/src/ur_robotiq_servo/test/test_flake8.py b/src/ur_robotiq_servo/test/test_flake8.py new file mode 100644 index 0000000..27ee107 --- /dev/null +++ b/src/ur_robotiq_servo/test/test_flake8.py @@ -0,0 +1,25 @@ +# Copyright 2017 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_flake8.main import main_with_errors +import pytest + + +@pytest.mark.flake8 +@pytest.mark.linter +def test_flake8(): + rc, errors = main_with_errors(argv=[]) + assert rc == 0, \ + 'Found %d code style errors / warnings:\n' % len(errors) + \ + '\n'.join(errors) diff --git a/src/ur_robotiq_servo/test/test_pep257.py b/src/ur_robotiq_servo/test/test_pep257.py new file mode 100644 index 0000000..b234a38 --- /dev/null +++ b/src/ur_robotiq_servo/test/test_pep257.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_pep257.main import main +import pytest + + +@pytest.mark.linter +@pytest.mark.pep257 +def test_pep257(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found code style errors / warnings' diff --git a/src/ur_robotiq_servo/ur_robotiq_servo/__init__.py b/src/ur_robotiq_servo/ur_robotiq_servo/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/ur_robotiq_servo/ur_robotiq_servo/ps5_control.py b/src/ur_robotiq_servo/ur_robotiq_servo/ps5_control.py new file mode 100644 index 0000000..e69de29