I ran colcon build and then sourced setup.sh and then ran launch file. I am getting the error below.
ros2 launch follow_wall follow_wall_launch_file.launch.py
[INFO] [launch]: All log files can be found below /home/user/.ros/log/2024-05-25-17-10-30-812530-3_xterm-6835
[INFO] [launch]: Default logging verbosity is set to INFO
[ERROR] [launch]: Caught exception in launch (see debug for traceback): package ‘follow_wall’ found at ‘/home/user/ros2_ws/install/follow_wall’, butlibexec directory ‘/home/user/ros2_ws/install/follow_wall/lib/follow_wall’ does not exist
import rclpy
# import the ROS2 python libraries
from rclpy.node import Node
# import the Twist module from geometry_msgs interface
from geometry_msgs.msg import Twist
# import the LaserScan module from sensor_msgs interface
from sensor_msgs.msg import Odometry
from rclpy.qos import ReliabilityPolicy, QoSProfile
# import numpy to calculate the qauternion
import numpy as np
class FollowWall(Node):
def __init__(self):
# Here you have the class constructor
# call the class constructor
super().__init__('follow_wall')
# create the publisher object
self.publisher_ = self.create_publisher(Twist, 'cmd_vel', 10)
# create the subscriber object
# Create the subscriber for the odom topic
self.odom_subscriber = rclpy.Subscriber("/odom", Odometry, self.odom_callback, QoSProfile(depth=10, reliability=ReliabilityPolicy.RELIABLE))
# define the timer period for 0.5 seconds
self.timer_period = 0.5
# define the variable to save the received info
self.laser_forward = 0
# create a Twist message
self.cmd = Twist()
self.timer = self.create_timer(self.timer_period, self.motion)
def odom_callback(self, data):
# Get the orientation of the robot from the odometry message
quaternion = data.pose.pose.orientation
# Convert the quaternion to Euler angles using the HINT 1 function
roll, pitch, yaw = euler_from_quaternion(quaternion)
# Calculate the robot's position and orientation
x = data.pose.pose.position.x
y = data.pose.pose.position.y
z = data.pose.pose.position.z
# Check if the robot is in parallel with the opening
if x > 0 and y < 1:
# If it is, move forward until it goes past the opening
self.cmd_vel_publisher.publish(Twist(linear=Vector3(x=1, y=0, z=0)))
rclpy.loginfo("Robot is in parallel with the opening.")
else:
# If it isn't, rotate 90º and then move forward
self.cmd_vel_publisher.publish(Twist(angular=Vector3(z=1.57)))
rclpy.loginfo("Robot is not in parallel with the opening.")
def euler_from_quaternion(self, quaternion):
"""
Converts quaternion (w in last place) to euler roll, pitch, yaw
quaternion = [x, y, z, w]
Below should be replaced when porting for ROS2 Python tf_conversions is done.
"""
x = quaternion[0]
y = quaternion[1]
z = quaternion[2]
w = quaternion[3]
sinr_cosp = 2 * (w * x + y * z)
cosr_cosp = 1 - 2 * (x * x + y * y)
roll = np.arctan2(sinr_cosp, cosr_cosp)
sinp = 2 * (w * y - z * x)
pitch = np.arcsin(sinp)
siny_cosp = 2 * (w * z + x * y)
cosy_cosp = 1 - 2 * (y * y + z * z)
yaw = np.arctan2(siny_cosp, cosy_cosp)
return roll, pitch, yaw
def main(args=None):
# initialize the ROS communication
rclpy.init(args=args)
# declare the node constructor
FollowWall = FollowWall()
# pause the program execution, waits for a request to kill the node (ctrl+c)
rclpy.spin(FollowWall)
# Explicity destroy the node
FollowWall.destroy_node()
# shutdown the ROS communication
rclpy.shutdown()
if __name__ == '__main__':
main()
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='follow_wall',
executable='follow_wall',
output='screen'),
])
from setuptools import setup
import os
from glob import glob
package_name = 'follow_wall'
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']),(os.path.join('share', package_name), glob('launch/*.launch.py'))
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='user',
maintainer_email='user@todo.todo',
description='TODO: Package description',
license='TODO: License declaration',
tests_require=['pytest'],
entry_points={
'console_scripts': [
],
},
)