-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdrive_pattern.py
More file actions
93 lines (73 loc) · 3.03 KB
/
Copy pathdrive_pattern.py
File metadata and controls
93 lines (73 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python3
"""Drive a turtle in a square pattern using direct velocity commands.
This script creates a ROS2 node that publishes Twist messages to
/turtle1/cmd_vel, making the turtle drive in a square. The turtle
leaves a visible trail so you can see the shape it draws.
Run with: python3 ~/drive_pattern.py
(Make sure turtlesim_node is already running in another terminal.)
"""
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
class DrivePattern(Node):
"""Publish velocity commands to drive the turtle in a pattern."""
def __init__(self):
super().__init__('drive_pattern')
self.publisher = self.create_publisher(Twist, '/turtle1/cmd_vel', 10)
# Timer fires every 0.1 seconds (10 Hz)
self.timer = self.create_timer(0.1, self.timer_callback)
# State machine: alternate between 'forward' and 'turn'
self.state = 'forward'
self.ticks = 0
# ============================================================
# TODO: Adjust these values to change the pattern!
# ============================================================
self.forward_ticks = 20 # Drive forward for 20 ticks (2.0 s)
self.turn_ticks = 16 # Turn for 16 ticks (1.6 s)
self.linear_speed = 1.0 # Forward speed (units/s)
self.angular_speed = 1.0 # Turn speed (rad/s)
self.sides_completed = 0
self.total_sides = 4 # TODO: Change for triangle (3), pentagon (5), etc.
# ============================================================
self.get_logger().info(
f'Drawing a {self.total_sides}-sided shape. '
f'Watch the TurtleSim window!'
)
def timer_callback(self):
"""Called every 0.1 s — decide whether to drive or turn."""
msg = Twist()
if self.sides_completed >= self.total_sides:
# Done — publish zeros to stop the turtle
self.publisher.publish(msg)
self.get_logger().info(
f'Pattern complete! Drew {self.sides_completed} sides.'
)
self.timer.cancel()
return
if self.state == 'forward':
msg.linear.x = self.linear_speed
msg.angular.z = 0.0
self.ticks += 1
if self.ticks >= self.forward_ticks:
self.ticks = 0
self.state = 'turn'
elif self.state == 'turn':
msg.linear.x = 0.0
msg.angular.z = self.angular_speed
self.ticks += 1
if self.ticks >= self.turn_ticks:
self.ticks = 0
self.state = 'forward'
self.sides_completed += 1
self.get_logger().info(
f'Side {self.sides_completed}/{self.total_sides} complete'
)
self.publisher.publish(msg)
def main(args=None):
rclpy.init(args=args)
node = DrivePattern()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()