Так тяжкий млат, Дробя стекло, кует булат А. С. Пушкин, «Полтава»
![]() | ![]() |
Счетчиков Юрий Андреевич
Слышу информацию, что достаточно тяжело проходить курс в заданном темпе
Только под высокой нагрузкой возможно эффективное обучение
Так тяжкий млат, Дробя стекло, кует булат А. С. Пушкин, «Полтава»
Упрощение рутины: сборка, запуск
Почему черепаха не каталась по квадрату?
Построение графиков в ROS
Обратная связь в ROS
Изучим робототехнику 200-летней давности (регуляторы)
sudo apt install ros-jazzy-aruco-opencv-msgsmik@mik-ubuntu-24:~/ros2$ tree -L 2
.
├── ros-usv-teleop
│ ├── README.md
│ └── usv_ws
├── sim
│ ├── libdecor-0.so.0
│ ├── libdecor-cairo.so
│ ├── UnityPlayer.so
│ ├── waterstriderunityURP_BurstDebugInformation_DoNotShip
│ ├── WS_SIM_UBUNTU
│ └── WS_SIM_UBUNTU_Data
└── ws
├── build
├── install
├── log
└── src.bashrc$ tail ~/.bashrc --line 5
source /opt/ros/jazzy/setup.bash
source ~/ros2/ros-usv-teleop/usv_ws/install/setup.bash
source ~/ros2/ws/install/setup.bashОбновить симулятор с облака (https://sdb.smtu.ru/nextcloud/s/simulator) , а также исходный код пакета ros-usv-teleop
~/ros2/ros-usv-teleop$ git pull
~/ros2/ros-usv-teleop$ cd usw_ws
~/ros2/ros-usv-teleop/usw_ws$ colcon build$ cd ~/ros2/ws/src
$ git clone http://sdb.smtu.ru/gitlab/marinerobotics/lesson_05.git
$ git clone http://sdb.smtu.ru/gitlab/robotics/ros_aruco_opencv.git
$ cd ..
$ colcon build --symlink-installcolcon build --symlink-install
File → Preferences → Settings
Text Editor → Files → Auto Save
After Delay

Launch-файлы — средства для одновременного запуска сразу нескольких нод + и настройка их параметров.
Могут быть написаны на python, xml, yaml
Могут быть вложенными
ros2 launch <package_name> <launch_file_name>ros2 launch lesson_05 mouse_teleop.launch.pyfrom launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='turtlesim',
namespace='turtlesim',
executable='turtlesim_node',
),
Node(
package="mouse_teleop",
executable='mouse_teleop',
namespace='turtlesim',
),
Node(
package="twist_stamper",
executable='twist_unstamper',
namespace='turtlesim',
remappings=[
('cmd_vel_in','mouse_vel'),
('cmd_vel_out', 'turtle1/cmd_vel')
],
),
])from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():
return LaunchDescription([
])Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
),ros2 launch lesson_05 main.launch.py lesson_num:=0И если мы поменяем код и перезапустим launch - изменения сразу применятся
https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Launch/Creating-Launch-Files.html | |
https://design.ros2.org/articles/roslaunch.html |
мы поворачивали не на угол, а в течение какого-то времени
мы не знали свою ошибку и не могли корректировать её (система не была 'робастной')
![]() |
![]() |
сцепление колёс автомобиля с поверхностью
космическая ракета и порывы ветра
колебания температуры окружающей среды вокруг инкубатора
для древней паровой машины:
параметры топлива (угля)
скорость подачи угля
16** - Христиан Гюйгенс создаёт центробежный регулятор для ветряной мельницы
1788 - Джеймс Уатт адаптирует регулятор для паровой машины
Без регулятора с обратной связи паровая машина не могла применяться массово.
![]() |
![]() |
запускаем:
ros2 launch lesson_05 \
main.launch.py lesson_num:=0rqt
Plugins → Visualization → Plot
/ws/turtle1/pose/theta
x: 5.544444561004639
y: 5.544444561004639
theta: 0.0
linear_velocity: 0.0
angular_velocity: 0.0![]() |
![]() |
self.pose_subscriber = self.create_subscription(Pose, 'turtle1/pose',
self.pose_callback, 10) def pose_callback(self, msg):
self.get_logger().info('Current heading: "%f"' % msg.theta)ros2 launch lesson_05 main.launch.py lesson_num:=2self.main()
# ...
def main(self):
while True:
self.publish_twist(0, 90.0)
self.publish_twist(3.0, 0.0)
# ...
self.get_clock().sleep_for(Duration(seconds=1.0))self.SIDE_TIME = 2.0
self.timer = self.create_timer(self.SIDE_TIME, self.pub_timer_callback)
self.step = 0
#...
def pub_timer_callback(self):
if self.step % 2:
self.publish_twist(0, 90.0)
else:
self.publish_twist(3.0, 0.0)
self.step += 1И более никакого sleep_for !
def main():
rclpy.init()
node = AngleMover()
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.destroy_node()
try:
rclpy.shutdown()
except Exception:
passros2 launch lesson_05 main.launch.py lesson_num:=1self.desired_heading - уставка/целевое значение/setpoint
def pub_timer_callback(self):
self.desired_heading += math.pi / 2
if self.desired_heading >= math.pi:
self.desired_heading -= 2 * math.pi
self.get_logger().info('New angle setpoint: "%f"' % self.desired_heading) if msg.theta - self.desired_heading < 0:
msg_pub.angular.z = math.radians(90.0)
self.get_logger().info('Turn left')
else:
msg_pub.angular.z = math.radians(-90.0)
self.get_logger().info('Turn right')ros2 launch lesson_05 main.launch.py lesson_num:=31° - 359° = ?
def angle_diff(a1, a2):
a = a1-a2
return (a+math.pi)%(2*math.pi)-math.piros2 launch lesson_05 main.launch.py lesson_num:=4
http://wiki.roboforum.ru/index.php?title=%D0%9F%D0%B5%D1%80%D0%B5%D0%B2%D0%BE%D0%B4_%D1%81%D1%82%D0%B0%D1%82%D1%8C%D0%B8_%22%D0%9F%D1%80%D0%BE%D1%81%D1%82%D0%BE_%D0%BE_%D0%9F%D0%98%D0%94-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D0%B0%D1%85%22 | |
PID Without a PhD Tim Wescott, Wescott Design Services https://web2.qatar.cmu.edu/~gdicaro/16311-Fall17/slides/PID-without-PhD.pdf | https://web2.qatar.cmu.edu/~gdicaro/16311-Fall17/slides/PID-without-PhD.pdf |
from waterstrider_interfaces.msg import WsPose
# ...
self.pose_subscriber = self.create_subscription(WsPose,
'unity_pose', self.pose_callback, 10)
# ...ros2 launch lesson_05 main.launch.py lesson_num:=5


Магнитные компасы работают плохо, особенно в бассейне
Спутниковые компасы дорогие и в помещении не работают
Механические, волоконно-оптические, лазерные гироскопы очень дорогие и большие
Но печать - дешёвая!
![]() |
![]() |
В симуляторе - "aruco маркеры"
Маркер по центру бассейна поворачивается по alt
ros2 launch lesson_05 main.launch.py lesson_num:=6symlink-install
Launch-файлы
Зачем нужны регуляторы?
Построение графиков в ROS
Обратная связь в ROS
Регуляторы

Официальная информация про RQT https://docs.ros.org/en/jazzy/Concepts/Intermediate/About-RQt.html | https://docs.ros.org/en/jazzy/Concepts/Intermediate/About-RQt.html |
Просто о ПИД-алгоритмах http://wiki.roboforum.ru/index.php?title=Перевод_статьи_"Просто_о_ПИД-алгоритмах" | http://wiki.roboforum.ru/index.php?title=Перевод_статьи_"Просто_о_ПИД-алгоритмах" |
PID Without a PhD Tim Wescott, Wescott Design Services https://web2.qatar.cmu.edu/~gdicaro/16311-Fall17/slides/PID-without-PhD.pdf | https://web2.qatar.cmu.edu/~gdicaro/16311-Fall17/slides/PID-without-PhD.pdf |
Написать код, который заставит катамаран в симуляторе двигаться приблизительно по квадрату
Попроще - адаптировать и настроить П-регулятор для катамарана в симуляторе (step_5.py)
Посложнее - написать свой ПД-регулятор и подобрать коэффициенты, он будет работать лучше
Практическое задание на настоящем катамаране (но отлаживаться можно и на симуляторе): следовать за курсовым углом Aruco-маркера (step_6.py)
Базовый код: https://sdb.smtu.ru/gitlab/marinerobotics/lesson-05/