Skip to content
Commits on Source (2)
from launch import LaunchDescription from launch import LaunchDescription
from launch_ros.actions import Node from launch_ros.actions import Node
def generate_launch_description(): def generate_launch_description():
return LaunchDescription([ return LaunchDescription([
Node( Node(
...@@ -15,5 +14,11 @@ def generate_launch_description(): ...@@ -15,5 +14,11 @@ def generate_launch_description():
namespace='', namespace='',
executable='step_4', executable='step_4',
name='square' name='square'
),
Node(
package='rqt_gui',
namespace='',
executable='rqt_gui',
name='rqt'
) )
]) ])
\ No newline at end of file
...@@ -7,46 +7,54 @@ import math ...@@ -7,46 +7,54 @@ import math
def angle_diff(a1, a2): def angle_diff(a1, a2):
a = a1-a2 a = a1 - a2
return (a+math.pi)%(2*math.pi)-math.pi return (a + math.pi) % (2 * math.pi) - math.pi
class RurMover(Node): class RurMover(Node):
def __init__(self): def __init__(self):
super().__init__('minimal_publisher') super().__init__('rur_mover')
self.publisher_twist = self.create_publisher(Twist, 'turtle1/cmd_vel', 10) self.publisher_twist = self.create_publisher(Twist, 'turtle1/cmd_vel', 10)
self.pose_subscriber = self.create_subscription(Pose, 'turtle1/pose', self.pose_callback, 10) self.pose_subscriber = self.create_subscription(Pose, 'turtle1/pose', self.pose_callback, 10)
self.desired_heading = - math.pi / 2 self.desired_heading = -math.pi / 2
self.SIDE_TIME = 5.0 self.SIDE_TIME = 5.0
self.LINEAR_SPEED = 0.5 self.BASE_LINEAR_SPEED = 0.5
self.timer = self.create_timer(self.SIDE_TIME, self.pub_timer_callback) self.Kp_angular = 1.0 # Пропорциональный коэффициент для угловой скорости
self.Kp_linear = 0.1 # Пропорциональный коэффициент для линейной скорости
self.timer = self.create_timer(self.SIDE_TIME, self.update_heading)
def pose_callback(self, msg): def pose_callback(self, msg):
self.get_logger().info('Current heading: "%f"' % msg.theta) self.log_current_state(msg)
self.get_logger().info('Setpoint: "%f"' % self.desired_heading) twist_msg = self.calculate_twist(msg.theta)
msg_pub = Twist() self.publisher_twist.publish(twist_msg)
msg_pub.linear.x = self.LINEAR_SPEED
error = angle_diff(self.desired_heading, msg.theta) def log_current_state(self, msg):
if error < 0: self.get_logger().info(f'Current heading: {msg.theta:.2f}')
msg_pub.angular.z = math.radians(90.0) self.get_logger().info(f'Setpoint: {self.desired_heading:.2f}')
self.get_logger().info('Turn left')
else: def calculate_twist(self, current_heading):
msg_pub.angular.z = math.radians(-90.0) error = angle_diff(self.desired_heading, current_heading)
self.get_logger().info('Turn right') angular_z = self.Kp_angular * error
self.publisher_twist.publish(msg_pub) linear_x = max(0.0, self.BASE_LINEAR_SPEED - self.Kp_linear * abs(error))
def pub_timer_callback(self): self.get_logger().info(f'Error: {error:.2f}, Angular velocity: {angular_z:.2f}')
self.get_logger().info(f'Linear velocity: {linear_x:.2f}')
twist_msg = Twist()
twist_msg.linear.x = linear_x
twist_msg.angular.z = angular_z
return twist_msg
def update_heading(self):
self.desired_heading += math.pi / 2 self.desired_heading += math.pi / 2
self.desired_heading %= 2 * math.pi self.desired_heading %= 2 * math.pi
self.get_logger().info('New angle setpoint: "%f"' % self.desired_heading) self.get_logger().info(f'New angle setpoint: {self.desired_heading:.2f}')
def main(args=None): def main(args=None):
rclpy.init(args=args) rclpy.init(args=args)
mover = RurMover() mover = RurMover()
rclpy.spin(mover) rclpy.spin(mover)
mover.destroy_node() mover.destroy_node()
rclpy.shutdown() rclpy.shutdown()
......