diff --git a/README.md b/README.md
index 018616e..64aaa75 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ Ref: https://docs.ros.org/en/foxy/Tutorials/Beginner-Client-Libraries/Creating-A
cd ~
```
-4. Go to src folder in your workspace
+4. Go to src folder in your workspace. Change my_name_ws accordingly
```shell script
cd my_name_ws/src/
@@ -55,6 +55,65 @@ sudo rosdep init
rosdep update
```
+5. Open VSCode, got to the menu and select file, an then select open folder and select our workspace in home. This show our workspace in the VScode explorer
+
+6. In a terminal go to your workspace
+
+```shell script
+colcon build
+```
+
+7. Sourve the overlay according to your distro
+
+```shell script
+source /opt/ros/foxy/setup.bash
+```
+8.
+
+```shell script
+. install/local_setup.bash
+```
+
+
+## Virtual Environment Setup in Linux
+
+https://docs.ros.org/en/foxy/How-To-Guides/Using-Python-Packages.html
+
+```shell script
+sudo apt install python3-pip
+```
+
+```shell script
+sudo apt install python3-virtualenv
+```
+### Make a virtual env and activate it
+
+From your workspace directory run this command
+
+```shell script
+virtualenv -p python3 ./venv
+```
+```shell script
+source ./venv/bin/activate
+```
+
+Make sure that colcon doesn’t try to build the venv
+```shell script
+touch ./venv/COLCON_IGNORE
+```
+
+
+Next, install the Python packages that you want in your virtual environment:
+
+if any requirement file is in the src folder, then install them for command line
+
+```shell script
+pip install -r src/requirements.txt
+```
+
+Now you can build your workspace and run your python node that depends on packages installed in your virtual environment.
+
+
## Source Control Recommendations
@@ -66,3 +125,8 @@ rosdep update
BUENOS DIAS :)
+ADIOS
+hola willy
+HOla reyes
+
+Feliz cumpleaños willy :)
diff --git a/henry_pkg/henry_pkg/__init__.py b/henry_pkg/henry_pkg/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/henry_pkg/henry_pkg/fis.py b/henry_pkg/henry_pkg/fis.py
new file mode 100644
index 0000000..cebfbda
--- /dev/null
+++ b/henry_pkg/henry_pkg/fis.py
@@ -0,0 +1,33 @@
+import numpy as np
+import skfuzzy as fuzz
+from skfuzzy import control as ctrl
+
+# New Antecedent/Consequent objects hold universe variables and membership
+# functions
+quality = ctrl.Antecedent(np.arange(0, 11, 1), 'quality')
+service = ctrl.Antecedent(np.arange(0, 11, 1), 'service')
+tip = ctrl.Consequent(np.arange(0, 26, 1), 'tip')
+
+# Auto-membership function population is possible with .automf(3, 5, or 7)
+quality.automf(3)
+service.automf(3)
+
+# Custom membership functions can be built interactively with a familiar,
+# Pythonic API
+tip['low'] = fuzz.trimf(tip.universe, [0, 0, 13])
+tip['medium'] = fuzz.trimf(tip.universe, [0, 13, 25])
+tip['high'] = fuzz.trimf(tip.universe, [13, 25, 25])
+
+rule1 = ctrl.Rule(quality['poor'] | service['poor'], tip['low'])
+rule2 = ctrl.Rule(service['average'], tip['medium'])
+rule3 = ctrl.Rule(service['good'] | quality['good'], tip['high'])
+
+rule1.view()
+
+tipping_ctrl = ctrl.ControlSystem([rule1, rule2, rule3])
+
+def main(args=None):
+ print()
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/henry_pkg/henry_pkg/my_pub.py b/henry_pkg/henry_pkg/my_pub.py
new file mode 100644
index 0000000..fff0ae1
--- /dev/null
+++ b/henry_pkg/henry_pkg/my_pub.py
@@ -0,0 +1,39 @@
+import rclpy
+from rclpy.node import Node
+
+from std_msgs.msg import String
+
+
+class MinimalPublisher(Node):
+
+ def __init__(self):
+ super().__init__('minimal_publisher')
+ self.publisher_ = self.create_publisher(String, 'topic', 10)
+ timer_period = 0.5 # seconds
+ self.timer = self.create_timer(timer_period, self.timer_callback)
+ self.i = 0
+
+ def timer_callback(self):
+ msg = String()
+ msg.data = 'Hello World: %d' % self.i
+ self.publisher_.publish(msg)
+ self.get_logger().info('Publishing: "%s"' % msg.data)
+ self.i += 1
+
+
+def main(args=None):
+ rclpy.init(args=args)
+
+ minimal_publisher = MinimalPublisher()
+
+ rclpy.spin(minimal_publisher)
+
+ # Destroy the node explicitly
+ # (optional - otherwise it will be done automatically
+ # when the garbage collector destroys the node object)
+ minimal_publisher.destroy_node()
+ rclpy.shutdown()
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/henry_pkg/henry_pkg/server.py b/henry_pkg/henry_pkg/server.py
new file mode 100644
index 0000000..cfd482f
--- /dev/null
+++ b/henry_pkg/henry_pkg/server.py
@@ -0,0 +1,55 @@
+import rclpy
+from rclpy.node import Node
+from sensor_msgs.msg import Image
+from lolito_interfaces.srv import CaptureImage
+
+
+class ImageCaptureServer(Node):
+ def __init__(self):
+ super().__init__('image_capture_server')
+ self.srv = self.create_service(CaptureImage, 'capture_image', self.capture_image_callback)
+
+ def capture_image_callback(self, request, response):
+ # Aquí es donde capturamos la imagen y la enviamos como respuesta
+ image = self.capture_image()
+ response.image = image
+ return response
+
+ def capture_image(self):
+ # En este ejemplo, utilizamos la biblioteca OpenCV para capturar la imagen
+ import cv2
+
+ # Capturamos la imagen de la cámara web
+ cap = cv2.VideoCapture(0)
+ _, frame = cap.read()
+
+ # Convertimos la imagen capturada a un mensaje ROS
+ msg = Image()
+ msg.header.frame_id = 'camera'
+ msg.encoding = 'bgr8'
+ msg.height, msg.width, _ = frame.shape
+ msg.step = 3 * msg.width
+ msg.data = frame.tobytes()
+
+ # Liberamos la cámara web
+ cap.release()
+
+ return msg
+
+
+def main(args=None):
+ rclpy.init(args=args)
+
+ node = ImageCaptureServer()
+
+ try:
+ rclpy.spin(node)
+ except KeyboardInterrupt:
+ pass
+
+ node.destroy_node()
+ rclpy.shutdown()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/henry_pkg/package.xml b/henry_pkg/package.xml
new file mode 100644
index 0000000..abad098
--- /dev/null
+++ b/henry_pkg/package.xml
@@ -0,0 +1,30 @@
+
+
+
+ henry_pkg
+ 0.0.0
+ TODO: Package description
+ roncanciovl
+ Apache License 2.0
+
+ rclpy
+ std_msgs
+ sensor_msgs
+ example_interfaces
+
+ rosidl_default_generators
+ rosidl_default_runtime
+ rosidl_interface_packages
+
+
+
+ ament_copyright
+
+ ament_flake8
+ ament_pep257
+ python3-pytest
+
+
+ ament_python
+
+
diff --git a/henry_pkg/resource/henry_pkg b/henry_pkg/resource/henry_pkg
new file mode 100644
index 0000000..e69de29
diff --git a/henry_pkg/setup.cfg b/henry_pkg/setup.cfg
new file mode 100644
index 0000000..6beb4db
--- /dev/null
+++ b/henry_pkg/setup.cfg
@@ -0,0 +1,4 @@
+[develop]
+script-dir=$base/lib/henry_pkg
+[install]
+install-scripts=$base/lib/henry_pkg
diff --git a/henry_pkg/setup.py b/henry_pkg/setup.py
new file mode 100644
index 0000000..a3dc297
--- /dev/null
+++ b/henry_pkg/setup.py
@@ -0,0 +1,27 @@
+from setuptools import setup
+
+package_name = 'henry_pkg'
+
+setup(
+ name=package_name,
+ version='0.0.0',
+ packages=[package_name],
+ data_files=[
+ ('share/ament_index/resource_index/packages',
+ ['resource/' + package_name]),
+ ('share/' + package_name, ['package.xml']),
+ ],
+ install_requires=['setuptools'],
+ zip_safe=True,
+ maintainer='roncanciovl',
+ maintainer_email='henryroncanciovelandia@gmail.com',
+ description='TODO: Package description',
+ license='Apache License 2.0',
+ tests_require=['pytest'],
+ entry_points={
+ 'console_scripts': [
+ 'talker = henry_pkg.my_pub:main',
+ 'imageServer = henry_pkg.server:main',
+ ],
+ },
+)
diff --git a/henry_pkg/test/test_copyright.py b/henry_pkg/test/test_copyright.py
new file mode 100644
index 0000000..cc8ff03
--- /dev/null
+++ b/henry_pkg/test/test_copyright.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_copyright.main import main
+import pytest
+
+
+@pytest.mark.copyright
+@pytest.mark.linter
+def test_copyright():
+ rc = main(argv=['.', 'test'])
+ assert rc == 0, 'Found errors'
diff --git a/henry_pkg/test/test_flake8.py b/henry_pkg/test/test_flake8.py
new file mode 100644
index 0000000..27ee107
--- /dev/null
+++ b/henry_pkg/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/henry_pkg/test/test_pep257.py b/henry_pkg/test/test_pep257.py
new file mode 100644
index 0000000..b234a38
--- /dev/null
+++ b/henry_pkg/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/lolito/CMakeLists.txt b/lolito/CMakeLists.txt
new file mode 100644
index 0000000..69d94d8
--- /dev/null
+++ b/lolito/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.5)
+project(lolito)
+
+# Default to C99
+if(NOT CMAKE_C_STANDARD)
+ set(CMAKE_C_STANDARD 99)
+endif()
+
+# Default to C++14
+if(NOT CMAKE_CXX_STANDARD)
+ set(CMAKE_CXX_STANDARD 14)
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+# find dependencies
+find_package(ament_cmake REQUIRED)
+find_package(ament_cmake_python REQUIRED)
+find_package(rclpy REQUIRED)
+find_package(std_msgs REQUIRED)
+
+ament_python_install_package(Scripts/)
+
+install(PROGRAMS
+ Scripts/pub-raul.py
+ DESTINATION lib/${PROJECT_NAME}
+)
+# uncomment the following section in order to fill in
+# further dependencies manually.
+# find_package( REQUIRED)
+
+if(BUILD_TESTING)
+ find_package(ament_lint_auto REQUIRED)
+ # the following line skips the linter which checks for copyrights
+ # uncomment the line when a copyright and license is not present in all source files
+ #set(ament_cmake_copyright_FOUND TRUE)
+ # the following line skips cpplint (only works in a git repo)
+ # uncomment the line when this package is not in a git repo
+ #set(ament_cmake_cpplint_FOUND TRUE)
+ ament_lint_auto_find_test_dependencies()
+endif()
+
+ament_package()
diff --git a/lolito/Scripts/__init__.py b/lolito/Scripts/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/lolito/Scripts/pub-raul.py b/lolito/Scripts/pub-raul.py
new file mode 100644
index 0000000..89ca552
--- /dev/null
+++ b/lolito/Scripts/pub-raul.py
@@ -0,0 +1,41 @@
+#!usr/bin/env python3
+
+
+import rclpy
+from rclpy.node import Node
+
+from std_msgs.msg import String
+
+class MinimalPublisher(Node):
+
+ def __init__(self):
+ super().__init__('minimal_publisher')
+ self.publisher_ = self.create_publisher(String, 'topic', 10)
+ timer_period = 0.5 # seconds
+ self.timer = self.create_timer(timer_period, self.timer_callback)
+ self.i = 0
+
+ def timer_callback(self):
+ msg = String()
+ msg.data = 'Bless kchon %d' % self.i
+ self.publisher_.publish(msg)
+ self.get_logger().info('Publishing: "%s"' % msg.data)
+ self.i += 1
+
+
+def main(args=None):
+ rclpy.init(args=args)
+
+ minimal_publisher = MinimalPublisher()
+
+ rclpy.spin(minimal_publisher)
+
+ # Destroy the node explicitly
+ # (optional - otherwise it will be done automatically
+ # when the garbage collector destroys the node object)
+ minimal_publisher.destroy_node()
+ rclpy.shutdown()
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/lolito/lolito/__init__.py b/lolito/lolito/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/lolito/lolito/scripts/pubhen.py b/lolito/lolito/scripts/pubhen.py
new file mode 100755
index 0000000..65e1fad
--- /dev/null
+++ b/lolito/lolito/scripts/pubhen.py
@@ -0,0 +1,42 @@
+
+#!/home/roncanciovl/ros2class_ws/venv/bin/python3
+
+import rclpy
+from rclpy.node import Node
+
+from std_msgs.msg import String
+
+
+class MinimalPublisher(Node):
+
+ def __init__(self):
+ super().__init__('minimal_publisher')
+ self.publisher_ = self.create_publisher(String, 'topic', 10)
+ timer_period = 0.5 # seconds
+ self.timer = self.create_timer(timer_period, self.timer_callback)
+ self.i = 0
+
+ def timer_callback(self):
+ msg = String()
+ msg.data = 'Hello World: %d' % self.i
+ self.publisher_.publish(msg)
+ self.get_logger().info('Publishing: "%s"' % msg.data)
+ self.i += 1
+
+
+def main(args=None):
+ rclpy.init(args=args)
+
+ minimal_publisher = MinimalPublisher()
+
+ rclpy.spin(minimal_publisher)
+
+ # Destroy the node explicitly
+ # (optional - otherwise it will be done automatically
+ # when the garbage collector destroys the node object)
+ minimal_publisher.destroy_node()
+ rclpy.shutdown()
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/lolito/package.xml b/lolito/package.xml
new file mode 100644
index 0000000..cb09290
--- /dev/null
+++ b/lolito/package.xml
@@ -0,0 +1,22 @@
+
+
+
+ lolito
+ 0.0.0
+ TODO: Package description
+ roncanciovl
+ TODO: License declaration
+
+
+ ament_cmake
+ ament_cmake_python
+ rclpy
+ std_msgs
+
+ ament_lint_auto
+ ament_lint_common
+
+
+ ament_cmake
+
+
diff --git a/lolito_interfaces/CMakeLists.txt b/lolito_interfaces/CMakeLists.txt
new file mode 100644
index 0000000..aef6e8c
--- /dev/null
+++ b/lolito_interfaces/CMakeLists.txt
@@ -0,0 +1,44 @@
+cmake_minimum_required(VERSION 3.5)
+project(lolito_interfaces)
+
+# Default to C99
+if(NOT CMAKE_C_STANDARD)
+ set(CMAKE_C_STANDARD 99)
+endif()
+
+# Default to C++14
+if(NOT CMAKE_CXX_STANDARD)
+ set(CMAKE_CXX_STANDARD 14)
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+# find dependencies
+find_package(ament_cmake REQUIRED)
+find_package(sensor_msgs REQUIRED)
+find_package(rosidl_default_generators REQUIRED)
+
+rosidl_generate_interfaces(${PROJECT_NAME}
+ "srv/CaptureImage.srv"
+ DEPENDENCIES sensor_msgs # Add packages that above messages depend on, in this case geometry_msgs for Sphere.msg
+)
+# uncomment the following section in order to fill in
+# further dependencies manually.
+# find_package( REQUIRED)
+
+ament_export_dependencies(rosidl_default_runtime)
+
+if(BUILD_TESTING)
+ find_package(ament_lint_auto REQUIRED)
+ # the following line skips the linter which checks for copyrights
+ # uncomment the line when a copyright and license is not present in all source files
+ #set(ament_cmake_copyright_FOUND TRUE)
+ # the following line skips cpplint (only works in a git repo)
+ # uncomment the line when this package is not in a git repo
+ #set(ament_cmake_cpplint_FOUND TRUE)
+ ament_lint_auto_find_test_dependencies()
+endif()
+
+ament_package()
diff --git a/lolito_interfaces/package.xml b/lolito_interfaces/package.xml
new file mode 100644
index 0000000..d5e7244
--- /dev/null
+++ b/lolito_interfaces/package.xml
@@ -0,0 +1,26 @@
+
+
+
+ lolito_interfaces
+ 0.0.0
+ TODO: Package description
+ roncanciovl
+ TODO: License declaration
+ ament_cmake
+ sensor_msgs
+
+ rosidl_default_generators
+
+ rosidl_default_runtime
+
+ rosidl_interface_packages
+
+
+
+ ament_lint_auto
+ ament_lint_common
+
+
+ ament_cmake
+
+
diff --git a/lolito_interfaces/srv/CaptureImage.srv b/lolito_interfaces/srv/CaptureImage.srv
new file mode 100644
index 0000000..f0cd11e
--- /dev/null
+++ b/lolito_interfaces/srv/CaptureImage.srv
@@ -0,0 +1,3 @@
+bool req
+---
+sensor_msgs/Image my_image
\ No newline at end of file
diff --git a/raul_pkg/launch/python_parameters_launch.py b/raul_pkg/launch/python_parameters_launch.py
new file mode 100644
index 0000000..8b1831b
--- /dev/null
+++ b/raul_pkg/launch/python_parameters_launch.py
@@ -0,0 +1,36 @@
+from launch import LaunchDescription
+from launch_ros.actions import Node
+
+def generate_launch_description():
+ return LaunchDescription([
+ Node(
+ package='raul_pkg',
+ executable='rpm2ls',
+ name='lineal_speed_joaquin',
+ output='screen',
+ emulate_tty=True,
+ parameters=[
+ {'radius': 0.5}
+ ]
+ ),
+ Node(
+ package='raul_pkg',
+ executable='rpm2ls',
+ name='lineal_speed_juan',
+ output='screen',
+ emulate_tty=True,
+ parameters=[
+ {'radius': 0.3}
+ ]
+ ),
+ Node(
+ package='raul_pkg',
+ executable='rpmpub',
+ name='rpm_pub',
+ output='screen',
+ emulate_tty=True,
+ parameters=[
+ {'rpms':5}
+ ]
+ )
+ ])
\ No newline at end of file
diff --git a/raul_pkg/package.xml b/raul_pkg/package.xml
new file mode 100644
index 0000000..47215ec
--- /dev/null
+++ b/raul_pkg/package.xml
@@ -0,0 +1,31 @@
+
+
+
+ raul_pkg
+ 0.0.0
+ TODO: Package description
+ raul
+ Apache License 2.0
+
+ cv_bridge
+ cv_bridge
+ image_transport
+ image_transport
+ sensor_msgs
+ sensor_msgs
+ OpenCV
+ OpenCV
+ rclpy
+ std_msgs
+ ros2launch
+ ament_copyright
+ ament_flake8
+ ament_pep257
+ python3-pytest
+
+ lolito_interfaces
+ sensor_msgs
+
+ ament_python
+
+
diff --git a/raul_pkg/raul_pkg/__init__.py b/raul_pkg/raul_pkg/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/raul_pkg/raul_pkg/client.py b/raul_pkg/raul_pkg/client.py
new file mode 100644
index 0000000..9cc63b7
--- /dev/null
+++ b/raul_pkg/raul_pkg/client.py
@@ -0,0 +1,38 @@
+import rclpy
+from lolito_interfaces.srv import CaptureImage
+from sensor_msgs.msg import Image
+import cv2
+from cv_bridge import CvBridge
+
+def send_request(node):
+ client = node.create_client(CaptureImage, 'capture_image')
+ image_sub = node.create_subscription(Image, 'capture_image', handle_image, 10)
+ req = CaptureImage.Request()
+
+ while not client.wait_for_service(timeout_sec=1.0):
+ node.get_logger().info('Servicio no disponible, esperando...')
+
+ future = client.call_async(req)
+ rclpy.spin_until_future_complete(node, future)
+
+ if future.result() is not None:
+ node.get_logger().info('Respuesta: %d' % future.result().sum)
+ else:
+ node.get_logger().info('Error en la solicitud')
+
+def handle_image(msg):
+ bridge = CvBridge()
+ image = bridge.imgmsg_to_cv2(msg, desired_encoding='passthrough')
+ cv2.imshow('Imagen recibida', image)
+ cv2.waitKey(0)
+ pass
+
+def main(args=None):
+ rclpy.init(args=args)
+ node = rclpy.create_node('client_raul')
+ send_request(node)
+ node.destroy_node()
+ rclpy.shutdown()
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/raul_pkg/raul_pkg/pub_raul.py b/raul_pkg/raul_pkg/pub_raul.py
new file mode 100644
index 0000000..fff0ae1
--- /dev/null
+++ b/raul_pkg/raul_pkg/pub_raul.py
@@ -0,0 +1,39 @@
+import rclpy
+from rclpy.node import Node
+
+from std_msgs.msg import String
+
+
+class MinimalPublisher(Node):
+
+ def __init__(self):
+ super().__init__('minimal_publisher')
+ self.publisher_ = self.create_publisher(String, 'topic', 10)
+ timer_period = 0.5 # seconds
+ self.timer = self.create_timer(timer_period, self.timer_callback)
+ self.i = 0
+
+ def timer_callback(self):
+ msg = String()
+ msg.data = 'Hello World: %d' % self.i
+ self.publisher_.publish(msg)
+ self.get_logger().info('Publishing: "%s"' % msg.data)
+ self.i += 1
+
+
+def main(args=None):
+ rclpy.init(args=args)
+
+ minimal_publisher = MinimalPublisher()
+
+ rclpy.spin(minimal_publisher)
+
+ # Destroy the node explicitly
+ # (optional - otherwise it will be done automatically
+ # when the garbage collector destroys the node object)
+ minimal_publisher.destroy_node()
+ rclpy.shutdown()
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/raul_pkg/raul_pkg/pub_rpm.py b/raul_pkg/raul_pkg/pub_rpm.py
new file mode 100644
index 0000000..d4bb6d2
--- /dev/null
+++ b/raul_pkg/raul_pkg/pub_rpm.py
@@ -0,0 +1,42 @@
+import rclpy
+from rclpy.node import Node
+
+from std_msgs.msg import String
+
+RPMS = 3
+
+class MinimalPublisher(Node):
+
+ def __init__(self):
+ super().__init__('Nodo_RPM')
+ self.declare_parameter('rpms',RPMS)
+ self.publisher_ = self.create_publisher(String, 'RPM', 10)
+ timer_period = 1 # seconds
+ self.timer = self.create_timer(timer_period, self.timer_callback)
+ self.i = 0
+
+ def timer_callback(self):
+ rpmenv = self.get_parameter('rpms').value
+ msg = String()
+ msg.data = str(rpmenv)
+ self.publisher_.publish(msg)
+ self.get_logger().info('Publishing: "%s"' % msg.data)
+ self.i += 1
+
+
+def main(args=None):
+ rclpy.init(args=args)
+
+ minimal_publisher = MinimalPublisher()
+
+ rclpy.spin(minimal_publisher)
+
+ # Destroy the node explicitly
+ # (optional - otherwise it will be done automatically
+ # when the garbage collector destroys the node object)
+ minimal_publisher.destroy_node()
+ rclpy.shutdown()
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/raul_pkg/raul_pkg/rpm2ls.py b/raul_pkg/raul_pkg/rpm2ls.py
new file mode 100644
index 0000000..e9b3755
--- /dev/null
+++ b/raul_pkg/raul_pkg/rpm2ls.py
@@ -0,0 +1,39 @@
+import rclpy
+from rclpy.node import Node
+from std_msgs.msg import String
+
+WHEEL_RADIUS = 5 #en cm
+
+class MyNode(Node):
+
+ def __init__(self):
+ super().__init__('node_lineal_speed')
+ self.declare_parameter('radius',WHEEL_RADIUS)
+ self.publisher_ = self.create_publisher(String, 'lineal_speed', 10)
+ self.subscription = self.create_subscription(
+ String,
+ 'RPM',
+ self.listener_callback,
+ 10)
+ self.subscription # prevent unused variable warning
+
+ def listener_callback(self, msg):
+ #self.get_logger().info('I heard: "%s"' % msg.data)
+ radio = self.get_parameter('radius').value
+ numin=(float(msg.data)/60)*2*3.141516*radio
+ print(numin)
+ msg.data=str(numin)
+ self.publisher_.publish(msg)
+
+def main(args=None):
+ rclpy.init(args=args)
+
+ my_node = MyNode()
+
+ rclpy.spin(my_node)
+
+ my_node.destroy_node()
+ rclpy.shutdown()
+
+if __name__ == '__main__':
+ main()
diff --git a/raul_pkg/raul_pkg/server.py b/raul_pkg/raul_pkg/server.py
new file mode 100644
index 0000000..7c82e51
--- /dev/null
+++ b/raul_pkg/raul_pkg/server.py
@@ -0,0 +1,57 @@
+#Create a node server to receive a message and capture photo and send to client
+# Path: src/willy_pkg/willy_pkg/probar.py
+# Compare this snippet from src/willy_pkg/willy_pkg/foto_servidor.py:
+
+import rclpy
+from rclpy.node import Node
+from sensor_msgs.msg import Image
+from lolito_interfaces.srv import CaptureImage
+
+class ImageCaptureServer(Node):
+ def __init__(self):
+ super().__init__('willy_server')
+ self.srv = self.create_service(CaptureImage, 'capture_image', self.capture_image_callback)
+
+ def capture_image_callback(self, request, response):
+ # Aquí es donde capturamos la imagen y la enviamos como respuesta
+ image = self.capture_image()
+ response.image = image
+ return response
+
+ def capture_image(self):
+ # En este ejemplo, utilizamos la biblioteca OpenCV para capturar la imagen
+ import cv2
+
+ # Capturamos la imagen de la cámara web
+ cap = cv2.VideoCapture(0)
+ _, frame = cap.read()
+
+ # Convertimos la imagen capturada a un mensaje ROS
+ msg = Image()
+ msg.header.frame_id = 'camera'
+ msg.encoding = 'bgr8'
+ msg.height, msg.width, _ = frame.shape
+ msg.step = 3 * msg.width
+ msg.data = frame.tobytes()
+
+ # Liberamos la cámara web
+ cap.release()
+
+ return msg
+
+
+def main(args=None):
+ rclpy.init(args=args)
+
+ node = ImageCaptureServer()
+
+ try:
+ rclpy.spin(node)
+ except KeyboardInterrupt:
+ pass
+
+ node.destroy_node()
+ rclpy.shutdown()
+
+if __name__ == '__main__':
+ main()
diff --git a/raul_pkg/raul_pkg/sub_raul.py b/raul_pkg/raul_pkg/sub_raul.py
new file mode 100644
index 0000000..1e546d4
--- /dev/null
+++ b/raul_pkg/raul_pkg/sub_raul.py
@@ -0,0 +1,37 @@
+import rclpy
+from rclpy.node import Node
+
+from std_msgs.msg import String
+
+
+class MinimalSubscriber(Node):
+
+ def __init__(self):
+ super().__init__('node_Raul')
+ self.subscription = self.create_subscription(
+ String,
+ 'lineal_speed',
+ self.listener_callback,
+ 10)
+ self.subscription # prevent unused variable warning
+
+ def listener_callback(self, msg):
+ self.get_logger().info('I heard: "%s"' % msg.data)
+
+
+def main(args=None):
+ rclpy.init(args=args)
+
+ minimal_subscriber = MinimalSubscriber()
+
+ rclpy.spin(minimal_subscriber)
+
+ # Destroy the node explicitly
+ # (optional - otherwise it will be done automatically
+ # when the garbage collector destroys the node object)
+ minimal_subscriber.destroy_node()
+ rclpy.shutdown()
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/raul_pkg/resource/raul_pkg b/raul_pkg/resource/raul_pkg
new file mode 100644
index 0000000..e69de29
diff --git a/raul_pkg/setup.cfg b/raul_pkg/setup.cfg
new file mode 100644
index 0000000..8ca868b
--- /dev/null
+++ b/raul_pkg/setup.cfg
@@ -0,0 +1,4 @@
+[develop]
+script-dir=$base/lib/raul_pkg
+[install]
+install-scripts=$base/lib/raul_pkg
diff --git a/raul_pkg/setup.py b/raul_pkg/setup.py
new file mode 100644
index 0000000..367111c
--- /dev/null
+++ b/raul_pkg/setup.py
@@ -0,0 +1,33 @@
+from setuptools import setup
+import os
+from glob import glob
+
+package_name = 'raul_pkg'
+
+setup(
+ name=package_name,
+ version='0.0.0',
+ packages=[package_name],
+ data_files=[
+ (os.path.join('share', package_name), glob('launch/*launch.[pxy][yma]*')),
+ ('share/ament_index/resource_index/packages',
+ ['resource/' + package_name]),
+ ('share/' + package_name, ['package.xml']),
+ ],
+ install_requires=['setuptools'],
+ zip_safe=True,
+ maintainer='raul',
+ maintainer_email='alvaroraulurdanetag@gmail.com',
+ description='TODO: Package description',
+ license='Apache License 2.0',
+ tests_require=['pytest'],
+ entry_points={
+ 'console_scripts': [
+ 'talker = raul_pkg.pub_raul:main',
+ 'listener = raul_pkg.sub_raul:main',
+ 'rpm2ls = raul_pkg.rpm2ls:main',
+ 'rpmpub = raul_pkg.pub_rpm:main',
+ 'server = raul_pkg.server:main'
+ ],
+ },
+)
\ No newline at end of file
diff --git a/raul_pkg/test/test_copyright.py b/raul_pkg/test/test_copyright.py
new file mode 100644
index 0000000..cc8ff03
--- /dev/null
+++ b/raul_pkg/test/test_copyright.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_copyright.main import main
+import pytest
+
+
+@pytest.mark.copyright
+@pytest.mark.linter
+def test_copyright():
+ rc = main(argv=['.', 'test'])
+ assert rc == 0, 'Found errors'
diff --git a/raul_pkg/test/test_flake8.py b/raul_pkg/test/test_flake8.py
new file mode 100644
index 0000000..27ee107
--- /dev/null
+++ b/raul_pkg/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/raul_pkg/test/test_pep257.py b/raul_pkg/test/test_pep257.py
new file mode 100644
index 0000000..b234a38
--- /dev/null
+++ b/raul_pkg/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/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..a504033
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,76 @@
+action-tutorials-py==0.9.4
+ament-copyright==0.9.7
+ament-cppcheck==0.9.7
+ament-cpplint==0.9.7
+ament-flake8==0.9.7
+ament-index-python==1.1.0
+ament-lint==0.9.7
+ament-lint-cmake==0.9.7
+ament-package==0.9.5
+ament-pep257==0.9.7
+ament-uncrustify==0.9.7
+ament-xmllint==0.9.7
+demo-nodes-py==0.9.4
+domain-coordinator==0.9.2
+examples-rclpy-executors==0.9.4
+examples-rclpy-minimal-action-client==0.9.4
+examples-rclpy-minimal-action-server==0.9.4
+examples-rclpy-minimal-client==0.9.4
+examples-rclpy-minimal-publisher==0.9.4
+examples-rclpy-minimal-service==0.9.4
+examples-rclpy-minimal-subscriber==0.9.4
+henry-pkg==0.0.0
+launch==0.10.10
+launch-ros==0.11.7
+launch-testing==0.10.10
+launch-testing-ros==0.11.7
+launch-xml==0.10.10
+launch-yaml==0.10.10
+networkx==3.0
+numpy==1.24.2
+osrf-pycommon==0.1.11
+quality-of-service-demo-py==0.9.4
+ros2action==0.9.12
+ros2bag==0.3.9
+ros2cli==0.9.12
+ros2component==0.9.12
+ros2doctor==0.9.12
+ros2interface==0.9.12
+ros2launch==0.11.7
+ros2lifecycle==0.9.12
+ros2multicast==0.9.12
+ros2node==0.9.12
+ros2param==0.9.12
+ros2pkg==0.9.12
+ros2run==0.9.12
+ros2service==0.9.12
+ros2topic==0.9.12
+rosidl-runtime-py==0.9.1
+rpyutils==0.2.0
+rqt==1.1.2
+rqt-action==0.4.9
+rqt-console==1.1.2
+rqt-graph==1.1.3
+rqt-gui==1.1.2
+rqt-gui-py==1.1.2
+rqt-moveit==1.0.1
+rqt-msg==1.0.5
+rqt-plot==1.1.1
+rqt-publisher==1.3.0
+rqt-py-console==1.0.2
+rqt-reconfigure==1.0.8
+rqt-robot-dashboard==0.5.8
+rqt-robot-monitor==1.0.5
+rqt-robot-steering==1.0.0
+rqt-runtime-monitor==1.0.0
+rqt-service-caller==1.0.5
+rqt-shell==1.0.2
+rqt-srv==1.0.3
+rqt-tf-tree==1.0.2
+rqt-top==1.0.2
+rqt-topic==1.3.0
+scikit-fuzzy==0.4.2
+scipy==1.10.1
+sros2==0.9.5
+teleop-twist-keyboard==2.3.2
+topic-monitor==0.9.4