Загрузка данных
**square_publisher.py**
```python
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
import math
class SquarePublisher(Node):
LINEAR_SPEED = 1.0
ANGULAR_SPEED = math.pi / 2
SIDE_DURATION = 2.0
TURN_DURATION = 1.0
def __init__(self):
super().__init__('square_publisher')
self.publisher_ = self.create_publisher(Twist, '/turtle1/cmd_vel', 10)
self.timer_period = 0.1
self.timer = self.create_timer(self.timer_period, self.timer_callback)
self.state = 'forward'
self.reset_state()
self.declare_parameter('side_duration', 2.0)
self.get_logger().info('SquarePublisher node started')
def reset_state(self):
self.state = 'forward'
self.state_start_time = self.get_clock().now()
self.get_logger().info('State reset: starting from forward movement')
def timer_callback(self):
try:
if self.publisher_.get_subscription_count() == 0:
self.get_logger().warn('No subscribers on /turtle1/cmd_vel, is turtlesim running?')
return
side_duration = self.get_parameter('side_duration').value
msg = Twist()
current_time = self.get_clock().now()
state_elapsed_time = (current_time - self.state_start_time).nanoseconds / 1e9
if self.state == 'forward':
msg.linear.x = self.LINEAR_SPEED
msg.angular.z = 0.0
if state_elapsed_time >= side_duration:
self.state = 'turn'
self.state_start_time = self.get_clock().now()
self.get_logger().info('Turning 90 degrees...')
elif self.state == 'turn':
msg.linear.x = 0.0
msg.angular.z = self.ANGULAR_SPEED
if state_elapsed_time >= self.TURN_DURATION:
self.state = 'forward'
self.state_start_time = self.get_clock().now()
self.get_logger().info('Moving forward...')
self.publisher_.publish(msg)
except Exception as e:
self.get_logger().error(f'Error in timer_callback: {str(e)}')
def main(args=None):
rclpy.init(args=args)
square_publisher = SquarePublisher()
try:
rclpy.spin(square_publisher)
except KeyboardInterrupt:
square_publisher.get_logger().info('Node stopped by user')
except Exception as e:
square_publisher.get_logger().error(f'Unexpected error: {str(e)}')
finally:
square_publisher.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
```
**setup.py**
```python
from setuptools import setup
package_name = 'lab_turtlesim'
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='student',
maintainer_email='student@university.edu',
description='Turtlesim lab package for ROS 2 learning',
license='Apache License 2.0',
tests_require=['pytest'],
entry_points={
'console_scripts': [
'square_publisher = lab_turtlesim.square_publisher:main',
],
},
)
```
**package.xml**
```xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypelayout="1.0"?>
<package format="3">
<name>lab_turtlesim</name>
<version>0.0.0</version>
<description>Turtlesim lab package for ROS 2 learning</description>
<maintainer email="student@university.edu">student</maintainer>
<license>Apache License 2.0</license>
<depend>rclpy</depend>
<depend>geometry_msgs</depend>
<depend>turtlesim</depend>
<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
<test_depend>ament_pep257</test_depend>
<test_depend>python3-pytest</test_depend>
<export>
<build_type>ament_python</build_type>
</export>
</package>
```