{"id":494654,"date":"2026-09-15T04:25:04","date_gmt":"2026-09-15T04:25:04","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=494654"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=494654","title":{"rendered":"\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430\u0445 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0440\u043e\u0431\u043e\u0442\u043e\u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0443\u0437\u043b\u043e\u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f. \u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0434\u043b\u044f <strong>\u0440\u043e\u0431\u043e\u0442\u0430-\u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438<\/strong>.<\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u0440\u043e\u0431\u043e\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u0434\u043e\u043b\u044c \u0440\u044f\u0434\u043e\u0432 \u0440\u0430\u0441\u0442\u0435\u043d\u0438\u0439, \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0440\u0430\u0431\u043e\u0447\u0438\u0445 \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u0445 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u044f\u0433\u043e\u0434 \u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u043c\u0435\u0442\u044c \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f, \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0449\u0438\u0435\u0441\u044f \u043d\u0430 \u043f\u0443\u0442\u0438.<\/p>\n<p>\u041f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0440\u043e\u0431\u043e\u0442-\u0441\u0431\u043e\u0440\u0449\u0438\u043a \u2014 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430. \u0412 \u043d\u0435\u0451 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0445\u043e\u0434\u0438\u0442\u044c \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c:<\/p>\n<pre><code>\u043c\u043e\u0431\u0438\u043b\u044c\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430        +\u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438        +\u043b\u0438\u0434\u0430\u0440 \/ \u0434\u0430\u0442\u0447\u0438\u043a\u0438        +\u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0437\u0440\u0435\u043d\u0438\u0435        +\u043f\u043e\u0438\u0441\u043a \u0441\u043f\u0435\u043b\u043e\u0439 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438        +\u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440        +\u0437\u0430\u0445\u0432\u0430\u0442 \u044f\u0433\u043e\u0434\u044b<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u044f \u0440\u0435\u0448\u0438\u043b \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f <strong>\u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/strong>: \u0440\u043e\u0431\u043e\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0435\u0445\u0430\u0442\u044c \u0438\u0437 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043a \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438, \u0430 \u043f\u0440\u0438 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0437\u0430\u043d\u044f\u0442\u0443\u044e \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f <strong>ROS 2, Python \u0438 Webots<\/strong>.<\/p>\n<h3>\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438<\/h3>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0440\u043e\u0431\u043e\u0442\u0430 \u043f\u043e \u0442\u0435\u043f\u043b\u0438\u0446\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043e.<\/p>\n<p>\u0420\u0430\u0431\u043e\u0447\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0441\u0435\u0442\u043a\u043e\u0439 5\u00d75:<\/p>\n<pre><code>20 21 22 23 2415 16 17 18 1910 11 12 13 14 5  6  7  8  9 0  1  2  3  4<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b.<\/p>\n<p>\u0422\u0430\u043a\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043a\u0430 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u043e\u0439 \u0442\u0435\u043f\u043b\u0438\u0446\u044b. \u041e\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432:<\/p>\n<pre><code>\u0433\u0434\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u043e\u0431\u043e\u0442?        \u2193\u043a\u0443\u0434\u0430 \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0435\u0445\u0430\u0442\u044c?        \u2193\u043a\u0430\u043a\u043e\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043a\u043e\u0440\u043e\u0447\u0435?        \u2193\u043a\u0430\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442?        \u2193\u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0434\u043e\u0440\u043e\u0433\u0430 \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0442\u0430?<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>START  = 0TARGET = 22<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0420\u043e\u0431\u043e\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043e\u0442 <code>0<\/code> \u0434\u043e <code>22<\/code>, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u0432 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435.<\/p>\n<p>\u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e, \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u0443\u044e \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u0432 \u0442\u0435\u043f\u043b\u0438\u0446\u0435: \u043f\u0440\u043e\u0445\u043e\u0434 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0442 \u044f\u0449\u0438\u043a\u043e\u043c, \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c.<\/p>\n<p>\u0420\u043e\u0431\u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u0438\u0434\u0430\u0440\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0437\u0430\u043d\u044f\u0442\u0443\u044e \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0438 \u043f\u0440\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u0443\u0436\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0451.<\/p>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code>\u0441\u0442\u0430\u0440\u0442  \u2193\u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430  \u2193\u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043f\u043e \u0442\u0435\u043f\u043b\u0438\u0446\u0435  \u2193\u0440\u0430\u0431\u043e\u0447\u0430\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f  \u2193\u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f  \u2193\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u044b  \u2193\u043f\u0435\u0440\u0435\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435  \u2193\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<hr\/>\n<h2>\u0427\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e<\/h2>\n<p>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0430 \u043d\u0430 \u0447\u0435\u0442\u044b\u0440\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430:<\/p>\n<pre><code>Graph\u2502\u251c\u2500\u2500 \u043a\u0430\u0440\u0442\u0430 \u043f\u043e\u043b\u044f\u251c\u2500\u2500 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u0430\u0440\u043a\u0435\u0440\u043e\u0432\u2514\u2500\u2500 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438Planner\u2502\u251c\u2500\u2500 BFS\u251c\u2500\u2500 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u2514\u2500\u2500 \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432Motion\u2502\u251c\u2500\u2500 Odometry\u251c\u2500\u2500 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e\u2514\u2500\u2500 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043c\u0430\u0440\u043a\u0435\u0440\u0430\u043c\u0438ObstacleDetector\u2502\u251c\u2500\u2500 LaserScan\u251c\u2500\u2500 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441\u043a\u0430\u043d\u043e\u0432\u2514\u2500\u2500 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043d\u044f\u0442\u043e\u0439 \u043a\u043b\u0435\u0442\u043a\u0438<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u044d\u0442\u0438 \u0447\u0430\u0441\u0442\u0438 \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439.<\/p>\n<p>[\u0414\u0430\u043b\u0435\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438: \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 Graph, BFS, \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432, Motion, Odometry, Twist, LaserScan \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f.]<\/p>\n<hr\/>\n<h2>\u041a\u0430\u043a \u044d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441\u043e \u0441\u0431\u043e\u0440\u043e\u043c \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438<\/h2>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0440\u043e\u0431\u043e\u0442 \u0435\u0449\u0451 <strong>\u043d\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u044f\u0433\u043e\u0434\u044b<\/strong>.<\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0438\u0436\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u2014 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u043d\u0430\u0434\u0451\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0440\u043e\u0431\u043e\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043a \u0440\u0430\u0431\u043e\u0447\u0438\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u043c.<\/p>\n<p>\u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code>                 \u0420\u041e\u0411\u041e\u0422-\u0421\u0411\u041e\u0420\u0429\u0418\u041a                       \u2502        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510        \u2502              \u2502              \u2502        \u2193              \u2193              \u2193   \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f      \u0422\u0435\u0445. \u0437\u0440\u0435\u043d\u0438\u0435    \u041c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440        \u2502              \u2502              \u2502        \u2193              \u2193              \u2193   \u043a\u0443\u0434\u0430 \u0435\u0445\u0430\u0442\u044c     \u0433\u0434\u0435 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0430    \u043a\u0430\u043a \u0441\u043e\u0440\u0432\u0430\u0442\u044c<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u0431\u044b\u0442\u0438\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0447\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u0440\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041a\u0430\u043c\u0435\u0440\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u044f\u0433\u043e\u0434\u044b:<\/p>\n<pre><code>\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435    \u2193\u043f\u043e\u0438\u0441\u043a \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438    \u2193\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u043f\u0435\u043b\u043e\u0441\u0442\u0438    \u2193\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u044f\u0433\u043e\u0434\u044b<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u0443:<\/p>\n<pre><code>\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u044f\u0433\u043e\u0434\u044b       \u2193\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f       \u2193\u043f\u043e\u0434\u0432\u043e\u0434 \u0437\u0430\u0445\u0432\u0430\u0442\u0430       \u2193\u0441\u0440\u044b\u0432       \u2193\u0443\u043a\u043b\u0430\u0434\u043a\u0430 \u044f\u0433\u043e\u0434\u044b<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u0435\u0442 \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0432 \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u0435 \u043f\u043e\u043b\u043d\u044b\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0446\u0438\u043a\u043b \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code>\u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442       \u2193\u043f\u0440\u0438\u0435\u0445\u0430\u0442\u044c \u043a \u0440\u0430\u0441\u0442\u0435\u043d\u0438\u044f\u043c       \u2193\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f       \u2193\u043d\u0430\u0439\u0442\u0438 \u0441\u043f\u0435\u043b\u044b\u0435 \u044f\u0433\u043e\u0434\u044b       \u2193\u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u0443       \u2193\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u044f\u0433\u043e\u0434\u044b       \u2193\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0440\u043e\u0445\u043e\u0434       \u2193\u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u044d\u0442\u043e\u0439 \u0446\u0435\u043f\u043e\u0447\u043a\u0438.<\/p>\n<hr\/>\n<h2>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/h2>\n<p>\u041d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u044d\u0442\u0430\u043f\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0440\u043e\u0431\u043e\u0442\u0430-\u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438.<\/p>\n<p>\u0420\u043e\u0431\u043e\u0442 \u0443\u043c\u0435\u0435\u0442:<\/p>\n<ul>\n<li>\n<p>\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0434\u0438\u0441\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u043e\u0439 5\u00d75;<\/p>\n<\/li>\n<li>\n<p>\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u043a\u0430\u0442\u044c \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442;<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0439 \u0434\u043b\u0438\u043d\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441 \u043c\u0435\u043d\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0443 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0434\u043e\u043c\u0435\u0442\u0440\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>Twist<\/code>;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 2D-\u043b\u0438\u0434\u0430\u0440\u0430;<\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0437\u0430\u043d\u044f\u0442\u0443\u044e \u043a\u043b\u0435\u0442\u043a\u0443;<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0435\u0451 \u0438\u0437 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e Nav2. \u0414\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u044d\u0442\u0430\u043f\u0430 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0435 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435\u043c.<\/p>\n<hr\/>\n<h2>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434<\/h2>\n<p>\u0412\u0435\u0441\u044c \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e Python-\u0444\u0430\u0439\u043b\u043e\u0432:<\/p>\n<pre><code>module_b_navigation\/\u2502\u251c\u2500\u2500 __init__.py\u251c\u2500\u2500 main.py\u251c\u2500\u2500 graph.py\u251c\u2500\u2500 planner.py\u251c\u2500\u2500 motion_controller.py\u2514\u2500\u2500 obstacle_detector.py<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><a href=\"http:\/\/graph.py\" rel=\"noopener nofollow\"><code>graph.py<\/code><\/a> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u043b\u044f 5\u00d75, \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b 25 \u043c\u0430\u0440\u043a\u0435\u0440\u043e\u0432 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0445 \u043a\u043b\u0435\u0442\u043e\u043a.<\/p>\n<p><a href=\"http:\/\/planner.py\" rel=\"noopener nofollow\"><code>planner.py<\/code><\/a> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 BFS-\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430, \u0437\u0430\u0442\u0435\u043c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432.<\/p>\n<p><code>motion_<\/code><a href=\"http:\/\/controller.py\" rel=\"noopener nofollow\"><code>controller.py<\/code><\/a> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. \u041f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0438\u0437:<\/p>\n<pre><code>\/RMC2\/odometry<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432:<\/p>\n<pre><code>\/RMC2\/cmd_vel<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>obstacle_<\/code><a href=\"http:\/\/detector.py\" rel=\"noopener nofollow\"><code>detector.py<\/code><\/a> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442:<\/p>\n<pre><code>\/RMC2\/scan<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 <code>LaserScan<\/code>, \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0441 \u043d\u043e\u0432\u044b\u043c \u0441\u043a\u0430\u043d\u043e\u043c \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0432\u043e\u0437\u043b\u0435 \u043a\u0430\u043a\u043e\u0433\u043e \u043c\u0430\u0440\u043a\u0435\u0440\u0430 \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435.<\/p>\n<p><a href=\"http:\/\/main.py\" rel=\"noopener nofollow\"><code>main.py<\/code><\/a> \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0432\u0441\u0451 \u0432 \u043e\u0434\u0438\u043d \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442:<\/p>\n<pre><code>\u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430\u2192 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435\u2192 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043b\u0438\u0434\u0430\u0440\u0430\u2192 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f\u2192 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043d\u044f\u0442\u043e\u0433\u043e \u043c\u0430\u0440\u043a\u0435\u0440\u0430\u2192 \u043f\u0435\u0440\u0435\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u2192 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u0417\u0430\u043f\u0443\u0441\u043a<\/h4>\n<p>\u0421\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043c\u0430\u0440\u043a\u0435\u0440\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 ROS 2.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"bash\">ros2 run &lt;package_name&gt; &lt;executable_name&gt; --ros-args \\    -p start_id:=0 \\    -p target_id:=22<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0440\u043e\u0431\u043e\u0442 \u0441\u0442\u0440\u043e\u0438\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0412 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0432 Webots:<\/p>\n<pre><code>\u0420\u041e\u0411\u041e\u0422 \u041e\u0421\u0422\u0410\u041d\u041e\u0412\u0418\u041b\u0421\u042f \u0412 \u0426\u0415\u041b\u0415\u0412\u041e\u0419 \u0422\u041e\u0427\u041a\u0415\u041f\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u041e\u0414\u041d\u041e \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0432 Webots.\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0432\u0435\u0434\u0438\u0442\u0435 y \u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 Enter.\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e? [y]:<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u0432\u043e\u0434\u0430:<\/p>\n<pre><code>y<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0441\u043a\u0430\u043d \u043b\u0438\u0434\u0430\u0440\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043d\u044f\u0442\u044b\u0439 \u043c\u0430\u0440\u043a\u0435\u0440 \u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.<\/p>\n<h4>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/h4>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u044f \u0432\u044b\u043b\u043e\u0436\u0438\u043b \u043d\u0430 GitHub:<\/p>\n<pre><code>[\u0417\u0414\u0415\u0421\u042c \u0421\u0421\u042b\u041b\u041a\u0410 \u041d\u0410 \u0420\u0415\u041f\u041e\u0417\u0418\u0422\u041e\u0420\u0418\u0419]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 ROS 2\/Webots.<\/p>\n<hr\/>\n<h2>\u0427\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435<\/h2>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u044d\u0442\u0430\u043f \u2014 \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u043a \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u0441\u0431\u043e\u0440\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438.<\/p>\n<p>\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437 \u043b\u0438\u0434\u0430\u0440\u0430 <strong>\u043d\u0435 \u043f\u043e\u0441\u043b\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438, \u0430 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f<\/strong>:<\/p>\n<pre><code>\u0440\u043e\u0431\u043e\u0442 \u0434\u0432\u0438\u0436\u0435\u0442\u0441\u044f      \u2193\u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 lidar      \u2193\u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435?    \u2199           \u2198  \u043d\u0435\u0442            \u0434\u0430   \u2193              \u2193\u0435\u0434\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435    \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430                  \u2193             \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u044b                  \u2193             \u043d\u043e\u0432\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u0440\u0435\u043d\u0438\u044f \u0438 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u043e\u043c.<\/p>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u0441\u0442\u0430\u043d\u0435\u0442 \u0443\u0436\u0435 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0437\u0440\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438: \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u044f\u0433\u043e\u0434\u044b, \u043e\u0446\u0435\u043d\u043a\u0430 \u0435\u0451 \u0441\u043f\u0435\u043b\u043e\u0441\u0442\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0434\u043b\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u0430.<\/p>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0446\u0438\u043a\u043b:<\/p>\n<pre><code>\u041d\u0410\u0412\u0418\u0413\u0410\u0426\u0418\u042f    \u2193\u0440\u043e\u0431\u043e\u0442 \u043f\u0440\u0438\u0435\u0445\u0430\u043b \u043a \u043a\u0443\u0441\u0442\u0443    \u2193\u0422\u0415\u0425\u041d\u0418\u0427\u0415\u0421\u041a\u041e\u0415 \u0417\u0420\u0415\u041d\u0418\u0415    \u2193\u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0441\u043f\u0435\u043b\u0430\u044f \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0430    \u2193\u041c\u0410\u041d\u0418\u041f\u0423\u041b\u042f\u0422\u041e\u0420    \u2193\u044f\u0433\u043e\u0434\u0430 \u0441\u043e\u0431\u0440\u0430\u043d\u0430    \u2193\u041d\u0410\u0412\u0418\u0413\u0410\u0426\u0418\u042f    \u2193\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0440\u0430\u0431\u043e\u0447\u0430\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u2014 \u044d\u0442\u043e \u043d\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0443\u0447\u0435\u0431\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u0430 \u043e\u0434\u0438\u043d \u0438\u0437 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0431\u043e\u0440\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438.<\/p>\n<h2>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438\u043c\u0435\u0440\u0430<\/h2>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0430 \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438.<\/p>\n<p>\u041f\u0440\u043e\u0435\u043a\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439:<\/p>\n<pre><code>module_b_navigation\/\u2502\u251c\u2500\u2500 __init__.py\u251c\u2500\u2500 main.py\u251c\u2500\u2500 graph.py\u251c\u2500\u2500 planner.py\u251c\u2500\u2500 motion_controller.py\u2514\u2500\u2500 obstacle_detector.py<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u043e\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u044b, \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e\u0439 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043b\u0438\u0434\u0430\u0440\u0430.<\/p>\n<h3>graph.py<\/h3>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0448\u0435 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 \u0442\u0435\u043f\u043b\u0438\u0446\u044b.<\/p>\n<pre><code class=\"python\">import mathclass Graph:    \"\"\"    \u041f\u0440\u043e\u0441\u0442\u0430\u044f \u043a\u0430\u0440\u0442\u0430 \u043f\u043e\u043b\u044f 5x5.    \u041d\u0443\u043c\u0435\u0440\u0430\u0446\u0438\u044f \u043c\u0430\u0440\u043a\u0435\u0440\u043e\u0432:        20 21 22 23 24        15 16 17 18 19        10 11 12 13 14         5  6  7  8  9         0  1  2  3  4    \u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u043c\u0438 \u043c\u0430\u0440\u043a\u0435\u0440\u0430\u043c\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u0440\u0430\u0432\u043d\u044b\u043c 1 \u043c\u0435\u0442\u0440\u0443.    \"\"\"    SIZE = 5    def valid(self, marker):        \"\"\"\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u0442\u0430\u043a\u043e\u0439 \u043c\u0430\u0440\u043a\u0435\u0440.\"\"\"        return 0 &lt;= marker &lt; 25    def position(self, marker):        \"\"\"        \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u0430\u0440\u043a\u0435\u0440\u0430.        \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:        marker = 12        x = 12 % 5  = 2        y = 12 \/\/ 5 = 2        \u0417\u043d\u0430\u0447\u0438\u0442 \u043c\u0430\u0440\u043a\u0435\u0440 12 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0442\u043e\u0447\u043a\u0435 (2, 2).        \"\"\"        x = marker % self.SIZE        y = marker \/\/ self.SIZE        return float(x), float(y)    def neighbors(self, marker, blocked=None):        \"\"\"        \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 \u043a\u043b\u0435\u0442\u043a\u0438.        \u041f\u043e\u0440\u044f\u0434\u043e\u043a:        \u0432\u043f\u0440\u0430\u0432\u043e -&gt; \u0432\u0432\u0435\u0440\u0445 -&gt; \u0432\u043b\u0435\u0432\u043e -&gt; \u0432\u043d\u0438\u0437.        \"\"\"        if blocked is None:            blocked = set()        row = marker \/\/ self.SIZE        col = marker % self.SIZE        result = []        # \u0412\u043f\u0440\u0430\u0432\u043e        if col &lt; self.SIZE - 1:            result.append(marker + 1)        # \u0412\u0432\u0435\u0440\u0445        if row &lt; self.SIZE - 1:            result.append(marker + self.SIZE)        # \u0412\u043b\u0435\u0432\u043e        if col &gt; 0:            result.append(marker - 1)        # \u0412\u043d\u0438\u0437        if row &gt; 0:            result.append(marker - self.SIZE)        # \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u0437\u0430\u043d\u044f\u0442\u044b\u0435 \u043a\u043b\u0435\u0442\u043a\u0438        return [m for m in result if m not in blocked]    def direction(self, a, b):        \"\"\"        \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u043c\u0438 \u043c\u0430\u0440\u043a\u0435\u0440\u0430\u043c\u0438.        \u041d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432.        \"\"\"        ax, ay = self.position(a)        bx, by = self.position(b)        if bx &gt; ax:            return \"RIGHT\"        if bx &lt; ax:            return \"LEFT\"        if by &gt; ay:            return \"UP\"        if by &lt; ay:            return \"DOWN\"    def nearest_marker(        self,        x,        y,        max_distance=0.75,        excluded=None    ):        \"\"\"        \u041f\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c \u0442\u043e\u0447\u043a\u0438 \u0438\u0449\u0435\u0442 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043c\u0430\u0440\u043a\u0435\u0440.        \u042d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043b\u0438\u0434\u0430\u0440\u0430:        \u043b\u0438\u0434\u0430\u0440 \u0434\u0430\u043b \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0443 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f -&gt;        \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u043e\u043c\u0435\u0440 \u043a\u043b\u0435\u0442\u043a\u0438.        \"\"\"        if excluded is None:            excluded = set()        best_marker = None        best_distance = 999999.0        for marker in range(25):            if marker in excluded:                continue            mx, my = self.position(marker)            distance = math.hypot(                x - mx,                y - my            )            if distance &lt; best_distance:                best_distance = distance                best_marker = marker        if best_distance &gt; max_distance:            return None        return best_marker<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<hr\/>\n<h3>planner.py<\/h3>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0438\u0441\u043a\u043e\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f BFS. \u041d\u043e \u0435\u0441\u043b\u0438 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0445 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0441 \u043c\u0435\u043d\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432.<\/p>\n<pre><code class=\"python\">from collections import dequeclass Planner:    \"\"\"    \u0421\u0442\u0440\u043e\u0438\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043f\u043e \u043a\u043b\u0435\u0442\u043a\u0430\u043c.    \u041a\u0440\u0438\u0442\u0435\u0440\u0438\u0438:    1. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0449\u0435\u043c \u0441\u0430\u043c\u044b\u0439 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.    2. \u0415\u0441\u043b\u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0445 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e,       \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0441 \u043c\u0435\u043d\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432.    3. \u0415\u0441\u043b\u0438 \u0438 \u044d\u0442\u043e \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e,       \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0441 \u043c\u0435\u043d\u044c\u0448\u0438\u043c\u0438 ID \u043c\u0430\u0440\u043a\u0435\u0440\u043e\u0432.    \"\"\"    def __init__(self, graph):        self.graph = graph    def count_turns(self, route):        \"\"\"\u0421\u0447\u0438\u0442\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432 \u0432 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0435.\"\"\"        if len(route) &lt; 3:            return 0        turns = 0        old_direction = self.graph.direction(            route[0],            route[1]        )        for i in range(1, len(route) - 1):            new_direction = self.graph.direction(                route[i],                route[i + 1]            )            if new_direction != old_direction:                turns += 1            old_direction = new_direction        return turns    def plan(self, start, target, blocked=None):        \"\"\"        \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442:            route, distance, turns        \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:            [0, 1, 2, 7, 12, 17, 22], 6, 1        \"\"\"        if blocked is None:            blocked = set()        if not self.graph.valid(start):            raise ValueError(                \"\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u043c\u0430\u0440\u043a\u0435\u0440\"            )        if not self.graph.valid(target):            raise ValueError(                \"\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043c\u0430\u0440\u043a\u0435\u0440\"            )        if start in blocked:            raise ValueError(                \"\u0421\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u044f \u043a\u043b\u0435\u0442\u043a\u0430 \u0437\u0430\u043d\u044f\u0442\u0430\"            )        if target in blocked:            raise ValueError(                \"\u0426\u0435\u043b\u0435\u0432\u0430\u044f \u043a\u043b\u0435\u0442\u043a\u0430 \u0437\u0430\u043d\u044f\u0442\u0430\"            )        if start == target:            return [start], 0, 0        # \u0412 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043b\u0435\u0436\u0430\u0442 \u0446\u0435\u043b\u044b\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b.        queue = deque()        queue.append([start])        # \u0417\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u0430\u043c\u044b\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b \u0434\u043e \u0446\u0435\u043b\u0438.        found_routes = []        shortest_length = None        while queue:            route = queue.popleft()            # \u0415\u0441\u043b\u0438 \u0443\u0436\u0435 \u043d\u0430\u0448\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442,            # \u044d\u0442\u043e\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e.            if shortest_length is not None:                if len(route) &gt; shortest_length:                    break            current = route[-1]            if current == target:                shortest_length = len(route)                found_routes.append(route)                continue            for next_marker in self.graph.neighbors(                current,                blocked            ):                # \u041d\u0435 \u0437\u0430\u0445\u043e\u0434\u0438\u043c \u0432\u0442\u043e\u0440\u043e\u0439 \u0440\u0430\u0437 \u0432 \u043a\u043b\u0435\u0442\u043a\u0443,                # \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0435.                if next_marker in route:                    continue                new_route = route + [next_marker]                queue.append(new_route)        if not found_routes:            raise RuntimeError(                \"\u041c\u0430\u0440\u0448\u0440\u0443\u0442 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\"            )        # \u0418\u0437 \u0432\u0441\u0435\u0445 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0445 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c:        # \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432,        # \u043f\u043e\u0442\u043e\u043c \u043f\u043e \u0441\u0430\u043c\u0438\u043c ID \u043c\u0430\u0440\u043a\u0435\u0440\u043e\u0432.        best_route = min(            found_routes,            key=lambda route: (                self.count_turns(route),                route            )        )        distance = len(best_route) - 1        turns = self.count_turns(best_route)        return best_route, distance, turns<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<hr\/>\n<h3>motion_controller.py<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u0435\u043d \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u0443\u044e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0432 Webots.<\/p>\n<p>\u041e\u043d \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u043e\u0434\u043e\u043c\u0435\u0442\u0440\u0438\u0438 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 <code>Twist<\/code>.<\/p>\n<pre><code class=\"python\">import mathfrom geometry_msgs.msg import Twistfrom nav_msgs.msg import Odometrydef angle_to_pi(angle):    \"\"\"    \u041f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0443\u0433\u043e\u043b \u043a \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0443 \u043e\u0442 -pi \u0434\u043e +pi.    \"\"\"    while angle &gt; math.pi:        angle -= 2 * math.pi    while angle &lt; -math.pi:        angle += 2 * math.pi    return angledef quaternion_to_yaw(q):    \"\"\"    ROS \u0445\u0440\u0430\u043d\u0438\u0442 \u043e\u0440\u0438\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u043a\u0430\u043a quaternion.    \u0414\u043b\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u043e \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d    \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0433\u043e\u043b \u0432\u043e\u043a\u0440\u0443\u0433 Z (yaw).    \"\"\"    sin_yaw = 2 * (        q.w * q.z +        q.x * q.y    )    cos_yaw = 1 - 2 * (        q.y * q.y +        q.z * q.z    )    return math.atan2(        sin_yaw,        cos_yaw    )class Motion:    \"\"\"    \u041f\u0440\u043e\u0441\u0442\u043e\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0440\u043e\u0431\u043e\u0442\u0430 \u043f\u043e \u0433\u043e\u0442\u043e\u0432\u043e\u043c\u0443 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0443.    \u041a\u043b\u0430\u0441\u0441:    - \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 odometry;    - \u0437\u043d\u0430\u0435\u0442 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0440\u043e\u0431\u043e\u0442\u0430;    - \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0440\u043e\u0431\u043e\u0442\u0430 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u043c\u0430\u0440\u043a\u0435\u0440\u0443;    - \u0435\u0434\u0435\u0442 \u043a \u043d\u0435\u043c\u0443;    - \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443.    \"\"\"    def __init__(self, node, graph):        self.node = node        self.graph = graph        # \u041a\u043e\u043c\u0430\u043d\u0434\u044b \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u043e\u0431\u043e\u0442\u0430        self.publisher = node.create_publisher(            Twist,            \"\/RMC2\/cmd_vel\",            10        )        # \u041f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0440\u043e\u0431\u043e\u0442\u0430        node.create_subscription(            Odometry,            \"\/RMC2\/odometry\",            self.odom_callback,            10        )        # \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u0435 0.05 \u0441\u0435\u043a\u0443\u043d\u0434\u044b        node.create_timer(            0.05,            self.control        )        self.x = None        self.y = None        self.yaw = None        self.route = []        self.index = 0        # \u041f\u043e\u043a\u0430 active == True,        # \u0440\u043e\u0431\u043e\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.        self.active = False        # \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u0438        self.linear_speed = 0.20        self.angular_speed = 0.60        # \u0414\u043e\u043f\u0443\u0441\u043a\u0438        self.distance_tolerance = 0.12        self.angle_tolerance = math.radians(5)    def odom_callback(self, msg):        \"\"\"\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0440\u043e\u0431\u043e\u0442\u0430.\"\"\"        self.x = msg.pose.pose.position.x        self.y = msg.pose.pose.position.y        self.yaw = quaternion_to_yaw(            msg.pose.pose.orientation        )    def start(self, route):        \"\"\"\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043f\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0443.\"\"\"        self.route = route        # route[0] \u2014 \u043a\u043b\u0435\u0442\u043a\u0430,        # \u0433\u0434\u0435 \u0440\u043e\u0431\u043e\u0442 \u0443\u0436\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f.        # \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441 route[1].        self.index = 1        if len(route) &lt; 2:            self.active = False            return        self.active = True        self.node.get_logger().info(            f\"movement_start route={route}\"        )    def stop(self):        \"\"\"\u041f\u043e\u0441\u044b\u043b\u0430\u0435\u0442 \u043d\u0443\u043b\u0435\u0432\u0443\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c.\"\"\"        self.publisher.publish(            Twist()        )    def finish(self):        \"\"\"\u041e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0440\u043e\u0431\u043e\u0442 \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.\"\"\"        self.stop()        self.active = False        self.node.get_logger().info(            \"movement_stop\"        )    def control(self):        \"\"\"        \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f.        1. \u0411\u0435\u0440\u0451\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043c\u0430\u0440\u043a\u0435\u0440.        2. \u0412\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c, \u0433\u0434\u0435 \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f.        3. \u0415\u0441\u043b\u0438 \u0440\u043e\u0431\u043e\u0442 \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0435 \u0442\u0443\u0434\u0430 \u2014 \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c\u0441\u044f.        4. \u0415\u0441\u043b\u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u0442\u0443\u0434\u0430 \u2014 \u0435\u0434\u0435\u043c \u043f\u0440\u044f\u043c\u043e.        5. \u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u0435\u0445\u0430\u043b\u0438 \u2014 \u0431\u0435\u0440\u0451\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043c\u0430\u0440\u043a\u0435\u0440.        \"\"\"        if not self.active:            return        # \u0416\u0434\u0451\u043c \u043f\u0435\u0440\u0432\u0443\u044e odometry.        if self.x is None:            return        # \u0415\u0441\u043b\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0441\u044f.        if self.index &gt;= len(self.route):            self.finish()            return        target = self.route[self.index]        target_x, target_y = self.graph.position(            target        )        dx = target_x - self.x        dy = target_y - self.y        distance = math.hypot(            dx,            dy        )        # \u0423\u0433\u043e\u043b, \u043a\u0443\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c.        target_yaw = math.atan2(            dy,            dx        )        # \u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e \u0443\u0433\u043b\u0443.        error = angle_to_pi(            target_yaw - self.yaw        )        # \u0423\u0436\u0435 \u043f\u0440\u0438\u0435\u0445\u0430\u043b\u0438 \u043a \u043c\u0430\u0440\u043a\u0435\u0440\u0443.        if distance &lt; self.distance_tolerance:            self.node.get_logger().info(                f\"marker_reached: {target}\"            )            self.stop()            self.index += 1            if self.index &gt;= len(self.route):                self.finish()            return        command = Twist()        # \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c\u0441\u044f.        if abs(error) &gt; self.angle_tolerance:            command.linear.x = 0.0            if error &gt; 0:                command.angular.z = (                    self.angular_speed                )            else:                command.angular.z = (                    -self.angular_speed                )        # \u041f\u043e\u0442\u043e\u043c \u0435\u0434\u0435\u043c \u043f\u0440\u044f\u043c\u043e.        else:            command.linear.x = self.linear_speed            # \u041d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0446\u0438\u044f \u043a\u0443\u0440\u0441\u0430.            command.angular.z = 1.2 * error            # \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430.            if command.angular.z &gt; 0.30:                command.angular.z = 0.30            if command.angular.z &lt; -0.30:                command.angular.z = -0.30        self.publisher.publish(            command        )<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<hr\/>\n<h3>obstacle_detector.py<\/h3>\n<p>\u042d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043b\u0438\u0434\u0430\u0440.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0441\u043a\u0430\u043d. \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043d\u043e\u0432\u044b\u0439 \u0441\u043a\u0430\u043d \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c.<\/p>\n<pre><code class=\"python\">import mathfrom rclpy.qos import qos_profile_sensor_datafrom sensor_msgs.msg import LaserScanclass ObstacleDetector:    \"\"\"    \u0418\u0449\u0435\u0442 \u041e\u0414\u041d\u041e \u043d\u043e\u0432\u043e\u0435 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435.    \u0418\u0434\u0435\u044f:    1. \u0414\u043e \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c lidar.    2. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u0442\u0430\u0432\u0438\u0442 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435.    3. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 lidar.    4. \u0418\u0449\u0435\u043c \u043b\u0443\u0447\u0438, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u043b\u043e\u0441\u044c.    5. \u041f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u044d\u0442\u0438 \u0442\u043e\u0447\u043a\u0438 \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u0438\u0440\u0430.    6. \u0421\u043c\u043e\u0442\u0440\u0438\u043c, \u0432\u043e\u0437\u043b\u0435 \u043a\u0430\u043a\u043e\u0433\u043e \u043c\u0430\u0440\u043a\u0435\u0440\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u0442\u0430\u043a\u0438\u0445 \u0442\u043e\u0447\u0435\u043a.    \"\"\"    def __init__(self, node, graph):        self.node = node        self.graph = graph        # \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043b\u0438\u0434\u0430\u0440\u0430.        self.scan = None        # \u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043e \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f.        self.baseline = None        node.create_subscription(            LaserScan,            \"\/RMC2\/scan\",            self.scan_callback,            qos_profile_sensor_data        )        # \u0415\u0441\u043b\u0438 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u043b\u043e\u0441\u044c \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043d\u0430 20 \u0441\u043c,        # \u0441\u0447\u0438\u0442\u0430\u0435\u043c, \u0447\u0442\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442.        self.min_change = 0.20        # \u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0430\u043b\u0435\u043a\u043e \u0442\u043e\u0447\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c        # \u043e\u0442 \u0446\u0435\u043d\u0442\u0440\u0430 \u043a\u043b\u0435\u0442\u043a\u0438.        self.max_marker_distance = 0.75        # \u041c\u0438\u043d\u0438\u043c\u0443\u043c lidar-\u0442\u043e\u0447\u0435\u043a,        # \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443.        self.min_votes = 3    def scan_callback(self, msg):        \"\"\"\u041f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0441\u0430\u043c\u044b\u0439 \u0441\u0432\u0435\u0436\u0438\u0439 scan.\"\"\"        self.scan = msg    def save_baseline(self):        \"\"\"        \u0417\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c lidar \u0434\u043e \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f.        \"\"\"        if self.scan is None:            return False        self.baseline = list(            self.scan.ranges        )        return True    def find_obstacle(        self,        robot_x,        robot_y,        robot_yaw,        excluded=None    ):        \"\"\"        \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u043c\u0435\u0440 \u0437\u0430\u043d\u044f\u0442\u043e\u0439 \u043a\u043b\u0435\u0442\u043a\u0438.        \u0415\u0441\u043b\u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u2014        \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 None.        \"\"\"        if excluded is None:            excluded = set()        if self.scan is None:            return None        if self.baseline is None:            return None        if len(self.baseline) != len(            self.scan.ranges        ):            return None        # votes:        # \u043a\u043b\u044e\u0447 = \u043d\u043e\u043c\u0435\u0440 \u043c\u0430\u0440\u043a\u0435\u0440\u0430        # \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 = \u0441\u043a\u043e\u043b\u044c\u043a\u043e lidar-\u0442\u043e\u0447\u0435\u043a        # \u043f\u043e\u043f\u0430\u043b\u043e \u0432\u043e\u0437\u043b\u0435 \u043d\u0435\u0433\u043e        votes = {}        # \u0414\u043b\u044f \u043b\u043e\u0433\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0442\u043e\u0447\u0435\u043a.        points = {}        for i in range(            len(self.scan.ranges)        ):            old_range = self.baseline[i]            new_range = self.scan.ranges[i]            # \u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0434\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439.            if not math.isfinite(new_range):                continue            if new_range &lt; self.scan.range_min:                continue            if new_range &gt; self.scan.range_max:                continue            # \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043b\u0438 \u0437\u0434\u0435\u0441\u044c \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442.            new_object = False            # \u0420\u0430\u043d\u044c\u0448\u0435 \u043b\u0438\u0434\u0430\u0440 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u0438\u0434\u0435\u043b,            # \u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0443\u0432\u0438\u0434\u0435\u043b \u043e\u0431\u044a\u0435\u043a\u0442.            if not math.isfinite(old_range):                new_object = True            # \u0418\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0442\u0430\u043b \u043c\u0438\u043d\u0438\u043c\u0443\u043c            # \u043d\u0430 20 \u0441\u043c \u0431\u043b\u0438\u0436\u0435.            elif (                old_range - new_range                &gt;= self.min_change            ):                new_object = True            if not new_object:                continue            # \u0423\u0433\u043e\u043b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043b\u0443\u0447\u0430 \u043b\u0438\u0434\u0430\u0440\u0430.            angle = (                self.scan.angle_min                + i * self.scan.angle_increment            )            # \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u043e\u0431\u043e\u0442\u0430.            local_x = (                new_range * math.cos(angle)            )            local_y = (                new_range * math.sin(angle)            )            # \u041f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u0442\u043e\u0447\u043a\u0443            # \u0432 \u043c\u0438\u0440\u043e\u0432\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b.            world_x = robot_x + (                local_x * math.cos(robot_yaw)                - local_y * math.sin(robot_yaw)            )            world_y = robot_y + (                local_x * math.sin(robot_yaw)                + local_y * math.cos(robot_yaw)            )            # \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043c\u0430\u0440\u043a\u0435\u0440.            marker = self.graph.nearest_marker(                world_x,                world_y,                self.max_marker_distance,                excluded            )            if marker is None:                continue            # \u0413\u043e\u043b\u043e\u0441\u0443\u0435\u043c \u0437\u0430 \u044d\u0442\u043e\u0442 \u043c\u0430\u0440\u043a\u0435\u0440.            votes[marker] = (                votes.get(marker, 0) + 1            )            if marker not in points:                points[marker] = []            points[marker].append(                (world_x, world_y)            )        if not votes:            return None        # \u041c\u0430\u0440\u043a\u0435\u0440 \u0441 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0433\u043e\u043b\u043e\u0441\u043e\u0432.        best_marker = max(            votes,            key=votes.get        )        self.node.get_logger().info(            f\"obstacle_votes=\"            f\"{dict(sorted(votes.items()))}\"        )        if votes[best_marker] &lt; self.min_votes:            return None        # \u0421\u0440\u0435\u0434\u043d\u044f\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 lidar-\u0442\u043e\u0447\u0435\u043a,        # \u043f\u0440\u043e\u0433\u043e\u043b\u043e\u0441\u043e\u0432\u0430\u0432\u0448\u0438\u0445 \u0437\u0430 \u043f\u043e\u0431\u0435\u0434\u0438\u0432\u0448\u0438\u0439 \u043c\u0430\u0440\u043a\u0435\u0440.        best_points = points[best_marker]        avg_x = (            sum(p[0] for p in best_points)            \/ len(best_points)        )        avg_y = (            sum(p[1] for p in best_points)            \/ len(best_points)        )        self.node.get_logger().info(            f\"obstacle_world_position\u2248\"            f\"({avg_x:.3f}, {avg_y:.3f})\"        )        return best_marker<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<hr\/>\n<h3>main.py<\/h3>\n<p>\u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0444\u0430\u0439\u043b.<\/p>\n<p>\u041e\u043d \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0438 \u043b\u0438\u0434\u0430\u0440 \u0432 \u043e\u0434\u0438\u043d \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442.<\/p>\n<pre><code class=\"python\">import rclpyfrom rclpy.node import Nodefrom module_b_navigation.graph import Graphfrom module_b_navigation.planner import Plannerfrom module_b_navigation.motion_controller import Motionfrom module_b_navigation.obstacle_detector import (    ObstacleDetector)def wait_robot(node, motion):    \"\"\"    \u041f\u043e\u043a\u0430 \u0440\u043e\u0431\u043e\u0442 \u0435\u0434\u0435\u0442,    \u0434\u0430\u0451\u043c ROS \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.    \"\"\"    while motion.active and rclpy.ok():        rclpy.spin_once(            node,            timeout_sec=0.1        )def wait_for_new_scan(node):    \"\"\"    \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f    \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c ROS-\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f,    \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0432\u0435\u0436\u0438\u0439 lidar scan.    \"\"\"    for i in range(10):        rclpy.spin_once(            node,            timeout_sec=0.1        )def print_route(    title,    start,    target,    blocked,    route,    distance,    turns):    \"\"\"\u041f\u0435\u0447\u0430\u0442\u0430\u0435\u0442 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.\"\"\"    print()    print(\"========================================\")    print(title)    print(\"========================================\")    print(\"Start marker :\", start)    print(\"Target marker:\", target)    print(\"Blocked      :\", sorted(blocked))    print()    print(\"ROUTE    :\", route)    print(\"DISTANCE :\", distance)    print(\"TURNS    :\", turns)    print(\"========================================\")    print()def main(args=None):    # \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c ROS.    rclpy.init(args=args)    node = Node(        \"module_b_navigation\"    )    # \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430.    node.declare_parameter(        \"start_id\",        0    )    node.declare_parameter(        \"target_id\",        22    )    start = node.get_parameter(        \"start_id\"    ).value    target = node.get_parameter(        \"target_id\"    ).value    # \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.    graph = Graph()    planner = Planner(        graph    )    motion = Motion(        node,        graph    )    detector = ObstacleDetector(        node,        graph    )    try:        # ==============================================        # 1. \u0421\u0422\u0420\u041e\u0418\u041c \u041c\u0410\u0420\u0428\u0420\u0423\u0422 \u0422\u0423\u0414\u0410        # ==============================================        blocked = set()        node.get_logger().info(            \"OUTBOUND_PLANNING_START\"        )        route, distance, turns = planner.plan(            start,            target,            blocked        )        print_route(            \"OUTBOUND ROUTE\",            start,            target,            blocked,            route,            distance,            turns        )        # ==============================================        # 2. \u0415\u0414\u0415\u041c \u041a \u0426\u0415\u041b\u0418        # ==============================================        node.get_logger().info(            \"OUTBOUND_MOVEMENT_START\"        )        motion.start(            route        )        wait_robot(            node,            motion        )        node.get_logger().info(            \"OUTBOUND_MOVEMENT_STOP\"        )        # ==============================================        # 3. \u0417\u0410\u041f\u041e\u041c\u0418\u041d\u0410\u0415\u041c \u041b\u0418\u0414\u0410\u0420        # ==============================================        if not detector.save_baseline():            node.get_logger().error(                \"BASELINE_SCAN_NOT_AVAILABLE\"            )            return        node.get_logger().info(            \"BASELINE_SCAN_CAPTURED\"        )        # ==============================================        # 4. \u041f\u041e\u041b\u042c\u0417\u041e\u0412\u0410\u0422\u0415\u041b\u042c \u0421\u0422\u0410\u0412\u0418\u0422 \u041f\u0420\u0415\u041f\u042f\u0422\u0421\u0422\u0412\u0418\u0415        # ==============================================        print()        print(\"========================================\")        print(\"\u0420\u041e\u0411\u041e\u0422 \u041e\u0421\u0422\u0410\u041d\u041e\u0412\u0418\u041b\u0421\u042f \u0412 \u0426\u0415\u041b\u0415\u0412\u041e\u0419 \u0422\u041e\u0427\u041a\u0415\")        print(\"========================================\")        print(            \"\u041f\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u041e\u0414\u041d\u041e \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0432 Webots.\"        )        print(            \"\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0432\u0435\u0434\u0438\u0442\u0435 y \u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 Enter.\"        )        print(\"========================================\")        while True:            answer = input(                \"\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e? [y]: \"            )            if answer.lower().strip() == \"y\":                break        # ==============================================        # 5. \u041f\u041e\u041b\u0423\u0427\u0410\u0415\u041c \u0421\u0412\u0415\u0416\u0418\u0419 \u041b\u0418\u0414\u0410\u0420        # ==============================================        wait_for_new_scan(            node        )        # ==============================================        # 6. \u0418\u0429\u0415\u041c \u0417\u0410\u041d\u042f\u0422\u0423\u042e \u041a\u041b\u0415\u0422\u041a\u0423        # ==============================================        node.get_logger().info(            \"OBSTACLE_SCAN_START\"        )        blocked_marker = detector.find_obstacle(            motion.x,            motion.y,            motion.yaw,            excluded={                start,                target            }        )        if blocked_marker is None:            print()            print(                \"\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e.\"            )            print()            return        print()        print(\"========================================\")        print(            \"OBSTACLE DETECTED ON MARKER\",            blocked_marker        )        print(\"========================================\")        print()        # \u042d\u0442\u0430 \u043a\u043b\u0435\u0442\u043a\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u0430.        blocked = {            blocked_marker        }        # ==============================================        # 7. \u0421\u0422\u0420\u041e\u0418\u041c \u041e\u0411\u0420\u0410\u0422\u041d\u042b\u0419 \u041c\u0410\u0420\u0428\u0420\u0423\u0422        # ==============================================        node.get_logger().info(            \"RETURN_PLANNING_START\"        )        return_route, distance, turns = (            planner.plan(                target,                start,                blocked            )        )        print_route(            \"RETURN ROUTE\",            target,            start,            blocked,            return_route,            distance,            turns        )        # ==============================================        # 8. \u0415\u0414\u0415\u041c \u041e\u0411\u0420\u0410\u0422\u041d\u041e        # ==============================================        node.get_logger().info(            \"RETURN_MOVEMENT_START\"        )        motion.start(            return_route        )        wait_robot(            node,            motion        )        node.get_logger().info(            \"RETURN_MOVEMENT_STOP\"        )        node.get_logger().info(            \"MODULE_B_DONE\"        )        print()        print(\"========================================\")        print(\"MODULE B COMPLETE\")        print(            \"Robot returned to the start marker.\"        )        print(\"========================================\")        print()    except KeyboardInterrupt:        pass    finally:        # \u041d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439        # \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0440\u043e\u0431\u043e\u0442.        motion.stop()        node.destroy_node()        rclpy.shutdown()if __name__ == \"__main__\":    main()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430<\/h3>\n<p>\u0412\u0435\u0441\u044c \u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u0441\u0432\u0435\u0441\u0442\u0438 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code>\u0440\u043e\u0431\u043e\u0442 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438          \u2193     START = 0          \u2193         BFS          \u2193   \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043a \u0440\u0430\u0441\u0442\u0435\u043d\u0438\u044f\u043c          \u2193       \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435          \u2193     TARGET = 22          \u2193   \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 LaserScan          \u2193  \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f          \u2193 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0434\u0432\u0443\u0445 \u0441\u043a\u0430\u043d\u043e\u0432          \u2193\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043d\u044f\u0442\u043e\u0439 \u043a\u043b\u0435\u0442\u043a\u0438          \u2193 blocked = {marker}          \u2193     \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 BFS          \u2193   \u043e\u0431\u0445\u043e\u0434 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f          \u2193\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a START<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u044d\u0442\u043e \u043f\u043e\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e \u0440\u043e\u0431\u043e\u0442\u0430-\u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430. \u0417\u0434\u0435\u0441\u044c \u0435\u0449\u0451 \u043d\u0435\u0442 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u044f\u0433\u043e\u0434, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043f\u0435\u043b\u043e\u0441\u0442\u0438 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u043e\u043c.<\/p>\n<p>\u041d\u043e \u0443\u0436\u0435 \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e\u0439, \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043e\u0434\u043e\u043c\u0435\u0442\u0440\u0438\u0435\u0439 \u0438 \u043b\u0438\u0434\u0430\u0440\u043e\u043c, \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f \u0438 \u043f\u0435\u0440\u0435\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u044d\u0442\u0430\u043f\u043e\u043c \u044d\u0442\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0437\u0440\u0435\u043d\u0438\u0435\u043c \u0438 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u043e\u043c:<\/p>\n<pre><code>\u041d\u0410\u0412\u0418\u0413\u0410\u0426\u0418\u042f     \u2193\u043f\u0440\u0438\u0435\u0445\u0430\u043b\u0438 \u043a \u0440\u0430\u0441\u0442\u0435\u043d\u0438\u044f\u043c     \u2193\u0422\u0415\u0425\u041d\u0418\u0427\u0415\u0421\u041a\u041e\u0415 \u0417\u0420\u0415\u041d\u0418\u0415     \u2193\u043d\u0430\u0448\u043b\u0438 \u0441\u043f\u0435\u043b\u0443\u044e \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0443     \u2193\u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u044f\u0433\u043e\u0434\u044b     \u2193\u041c\u0410\u041d\u0418\u041f\u0423\u041b\u042f\u0422\u041e\u0420     \u2193\u0441\u043e\u0440\u0432\u0430\u043b\u0438 \u044f\u0433\u043e\u0434\u0443     \u2193\u041d\u0410\u0412\u0418\u0413\u0410\u0426\u0418\u042f     \u2193\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0440\u0430\u0431\u043e\u0447\u0430\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u043c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043c\u043e\u0434\u0443\u043b\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u043a\u0440\u0443\u043f\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u2014 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u043e\u0431\u043e\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u0430 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0431\u043e\u0440\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438.<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1082262\/\">https:\/\/habr.com\/ru\/articles\/1082262\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430\u0445 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0440\u043e\u0431\u043e\u0442\u043e\u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0443\u0437\u043b\u043e\u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f. \u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0434\u043b\u044f \u0440\u043e\u0431\u043e\u0442\u0430-\u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438.\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u0440\u043e\u0431\u043e\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u0434\u043e\u043b\u044c \u0440\u044f\u0434\u043e\u0432 \u0440\u0430\u0441\u0442\u0435\u043d\u0438\u0439, \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0440\u0430\u0431\u043e\u0447\u0438\u0445 \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u0445 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u044f\u0433\u043e\u0434 \u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u043c\u0435\u0442\u044c \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f, \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0449\u0438\u0435\u0441\u044f \u043d\u0430 \u043f\u0443\u0442\u0438.\u041f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0440\u043e\u0431\u043e\u0442-\u0441\u0431\u043e\u0440\u0449\u0438\u043a \u2014 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430. \u0412 \u043d\u0435\u0451 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0445\u043e\u0434\u0438\u0442\u044c \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c:\u043c\u043e\u0431\u0438\u043b\u044c\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430        +\u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438        +\u043b\u0438\u0434\u0430\u0440 \/ \u0434\u0430\u0442\u0447\u0438\u043a\u0438        +\u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0437\u0440\u0435\u043d\u0438\u0435        +\u043f\u043e\u0438\u0441\u043a \u0441\u043f\u0435\u043b\u043e\u0439 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438        +\u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440        +\u0437\u0430\u0445\u0432\u0430\u0442 \u044f\u0433\u043e\u0434\u044b\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u044f \u0440\u0435\u0448\u0438\u043b \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438.\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c: \u0440\u043e\u0431\u043e\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0435\u0445\u0430\u0442\u044c \u0438\u0437 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043a \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438, \u0430 \u043f\u0440\u0438 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0437\u0430\u043d\u044f\u0442\u0443\u044e \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.\u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f ROS 2, Python \u0438 Webots.\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438\u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0440\u043e\u0431\u043e\u0442\u0430 \u043f\u043e \u0442\u0435\u043f\u043b\u0438\u0446\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043e.\u0420\u0430\u0431\u043e\u0447\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0441\u0435\u0442\u043a\u043e\u0439 5\u00d75:20 21 22 23 2415 16 17 18 1910 11 12 13 14 5  6  7  8  9 0  1  2  3  4\u041a\u0430\u0436\u0434\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b.\u0422\u0430\u043a\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043a\u0430 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u043e\u0439 \u0442\u0435\u043f\u043b\u0438\u0446\u044b. \u041e\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432:\u0433\u0434\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u043e\u0431\u043e\u0442?        \u2193\u043a\u0443\u0434\u0430 \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0435\u0445\u0430\u0442\u044c?        \u2193\u043a\u0430\u043a\u043e\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043a\u043e\u0440\u043e\u0447\u0435?        \u2193\u043a\u0430\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442?        \u2193\u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0434\u043e\u0440\u043e\u0433\u0430 \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0442\u0430?\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:START  = 0TARGET = 22\u0420\u043e\u0431\u043e\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043e\u0442 0 \u0434\u043e 22, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u0432 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438.\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435.\u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e, \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u0443\u044e \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u0432 \u0442\u0435\u043f\u043b\u0438\u0446\u0435: \u043f\u0440\u043e\u0445\u043e\u0434 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0442 \u044f\u0449\u0438\u043a\u043e\u043c, \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c.\u0420\u043e\u0431\u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u0438\u0434\u0430\u0440\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0437\u0430\u043d\u044f\u0442\u0443\u044e \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0438 \u043f\u0440\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u0443\u0436\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0451.\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:\u0441\u0442\u0430\u0440\u0442  \u2193\u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430  \u2193\u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043f\u043e \u0442\u0435\u043f\u043b\u0438\u0446\u0435  \u2193\u0440\u0430\u0431\u043e\u0447\u0430\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f  \u2193\u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f  \u2193\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u044b  \u2193\u043f\u0435\u0440\u0435\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435  \u2193\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c\u0427\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0430 \u043d\u0430 \u0447\u0435\u0442\u044b\u0440\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430:Graph\u2502\u251c\u2500\u2500 \u043a\u0430\u0440\u0442\u0430 \u043f\u043e\u043b\u044f\u251c\u2500\u2500 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u0430\u0440\u043a\u0435\u0440\u043e\u0432\u2514\u2500\u2500 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438Planner\u2502\u251c\u2500\u2500 BFS\u251c\u2500\u2500 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u2514\u2500\u2500 \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432Motion\u2502\u251c\u2500\u2500 Odometry\u251c\u2500\u2500 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e\u2514\u2500\u2500 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043c\u0430\u0440\u043a\u0435\u0440\u0430\u043c\u0438ObstacleDetector\u2502\u251c\u2500\u2500 LaserScan\u251c\u2500\u2500 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441\u043a\u0430\u043d\u043e\u0432\u2514\u2500\u2500 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043d\u044f\u0442\u043e\u0439 \u043a\u043b\u0435\u0442\u043a\u0438\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u044d\u0442\u0438 \u0447\u0430\u0441\u0442\u0438 \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439.[\u0414\u0430\u043b\u0435\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438: \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 Graph, BFS, \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432, Motion, Odometry, Twist, LaserScan \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f.]\u041a\u0430\u043a \u044d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441\u043e \u0441\u0431\u043e\u0440\u043e\u043c \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438\u041d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0440\u043e\u0431\u043e\u0442 \u0435\u0449\u0451 \u043d\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u044f\u0433\u043e\u0434\u044b.\u0421\u0435\u0439\u0447\u0430\u0441 \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0438\u0436\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u2014 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u043d\u0430\u0434\u0451\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0440\u043e\u0431\u043e\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043a \u0440\u0430\u0431\u043e\u0447\u0438\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u043c.\u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:                 \u0420\u041e\u0411\u041e\u0422-\u0421\u0411\u041e\u0420\u0429\u0418\u041a                       \u2502        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510        \u2502              \u2502              \u2502        \u2193              \u2193              \u2193   \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f      \u0422\u0435\u0445. \u0437\u0440\u0435\u043d\u0438\u0435    \u041c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440        \u2502              \u2502              \u2502        \u2193              \u2193              \u2193   \u043a\u0443\u0434\u0430 \u0435\u0445\u0430\u0442\u044c     \u0433\u0434\u0435 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0430    \u043a\u0430\u043a \u0441\u043e\u0440\u0432\u0430\u0442\u044c\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b.\u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u0431\u044b\u0442\u0438\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0447\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u0440\u0435\u043d\u0438\u044f.\u041a\u0430\u043c\u0435\u0440\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u044f\u0433\u043e\u0434\u044b:\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435    \u2193\u043f\u043e\u0438\u0441\u043a \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438    \u2193\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u043f\u0435\u043b\u043e\u0441\u0442\u0438    \u2193\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u044f\u0433\u043e\u0434\u044b\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u0443:\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u044f\u0433\u043e\u0434\u044b       \u2193\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f       \u2193\u043f\u043e\u0434\u0432\u043e\u0434 \u0437\u0430\u0445\u0432\u0430\u0442\u0430       \u2193\u0441\u0440\u044b\u0432       \u2193\u0443\u043a\u043b\u0430\u0434\u043a\u0430 \u044f\u0433\u043e\u0434\u044b\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u0435\u0442 \u0434\u0430\u043b\u044c\u0448\u0435.\u0422\u043e \u0435\u0441\u0442\u044c \u0432 \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u0435 \u043f\u043e\u043b\u043d\u044b\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0446\u0438\u043a\u043b \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:\u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442       \u2193\u043f\u0440\u0438\u0435\u0445\u0430\u0442\u044c \u043a \u0440\u0430\u0441\u0442\u0435\u043d\u0438\u044f\u043c       \u2193\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f       \u2193\u043d\u0430\u0439\u0442\u0438 \u0441\u043f\u0435\u043b\u044b\u0435 \u044f\u0433\u043e\u0434\u044b       \u2193\u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u0443       \u2193\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u044f\u0433\u043e\u0434\u044b       \u2193\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0440\u043e\u0445\u043e\u0434       \u2193\u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u044d\u0442\u043e\u0439 \u0446\u0435\u043f\u043e\u0447\u043a\u0438.\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u041d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u044d\u0442\u0430\u043f\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0440\u043e\u0431\u043e\u0442\u0430-\u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438.\u0420\u043e\u0431\u043e\u0442 \u0443\u043c\u0435\u0435\u0442:\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0434\u0438\u0441\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u043e\u0439 5\u00d75;\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438;\u0438\u0441\u043a\u0430\u0442\u044c \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442;\u043f\u0440\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0439 \u0434\u043b\u0438\u043d\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441 \u043c\u0435\u043d\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432;\u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0443 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0434\u043e\u043c\u0435\u0442\u0440\u0438\u0438;\u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 Twist;\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 2D-\u043b\u0438\u0434\u0430\u0440\u0430;\u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f;\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0437\u0430\u043d\u044f\u0442\u0443\u044e \u043a\u043b\u0435\u0442\u043a\u0443;\u0438\u0441\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0435\u0451 \u0438\u0437 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f;\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e Nav2. \u0414\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u044d\u0442\u0430\u043f\u0430 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0435 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435\u043c.\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434\u0412\u0435\u0441\u044c \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e Python-\u0444\u0430\u0439\u043b\u043e\u0432:module_b_navigation\/\u2502\u251c\u2500\u2500 __init__.py\u251c\u2500\u2500 main.py\u251c\u2500\u2500 graph.py\u251c\u2500\u2500 planner.py\u251c\u2500\u2500 motion_controller.py\u2514\u2500\u2500 obstacle_detector.pygraph.py \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u043b\u044f 5\u00d75, \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b 25 \u043c\u0430\u0440\u043a\u0435\u0440\u043e\u0432 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0445 \u043a\u043b\u0435\u0442\u043e\u043a.planner.py \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 BFS-\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430, \u0437\u0430\u0442\u0435\u043c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432.motion_controller.py \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. \u041f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0438\u0437:\/RMC2\/odometry\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432:\/RMC2\/cmd_velobstacle_detector.py \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442:\/RMC2\/scan\u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 LaserScan, \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0441 \u043d\u043e\u0432\u044b\u043c \u0441\u043a\u0430\u043d\u043e\u043c \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0432\u043e\u0437\u043b\u0435 \u043a\u0430\u043a\u043e\u0433\u043e \u043c\u0430\u0440\u043a\u0435\u0440\u0430 \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435.main.py \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0432\u0441\u0451 \u0432 \u043e\u0434\u0438\u043d \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442:\u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430\u2192 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435\u2192 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043b\u0438\u0434\u0430\u0440\u0430\u2192 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f\u2192 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043d\u044f\u0442\u043e\u0433\u043e \u043c\u0430\u0440\u043a\u0435\u0440\u0430\u2192 \u043f\u0435\u0440\u0435\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u2192 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u0417\u0430\u043f\u0443\u0441\u043a\u0421\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043c\u0430\u0440\u043a\u0435\u0440\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 ROS 2.\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:ros2 run &lt;package_name&gt; &lt;executable_name&gt; &#8212;ros-args \\    -p start_id:=0 \\    -p target_id:=22\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0440\u043e\u0431\u043e\u0442 \u0441\u0442\u0440\u043e\u0438\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435.\u0412 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0432 Webots:\u0420\u041e\u0411\u041e\u0422 \u041e\u0421\u0422\u0410\u041d\u041e\u0412\u0418\u041b\u0421\u042f \u0412 \u0426\u0415\u041b\u0415\u0412\u041e\u0419 \u0422\u041e\u0427\u041a\u0415\u041f\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u041e\u0414\u041d\u041e \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0432 Webots.\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0432\u0435\u0434\u0438\u0442\u0435 y \u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 Enter.\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e? [y]:\u041f\u043e\u0441\u043b\u0435 \u0432\u0432\u043e\u0434\u0430:y\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0441\u043a\u0430\u043d \u043b\u0438\u0434\u0430\u0440\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043d\u044f\u0442\u044b\u0439 \u043c\u0430\u0440\u043a\u0435\u0440 \u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439\u041f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u044f \u0432\u044b\u043b\u043e\u0436\u0438\u043b \u043d\u0430 GitHub:[\u0417\u0414\u0415\u0421\u042c \u0421\u0421\u042b\u041b\u041a\u0410 \u041d\u0410 \u0420\u0415\u041f\u041e\u0417\u0418\u0422\u041e\u0420\u0418\u0419]\u0412 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 ROS 2\/Webots.\u0427\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u044d\u0442\u0430\u043f \u2014 \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u043a \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u0441\u0431\u043e\u0440\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438.\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437 \u043b\u0438\u0434\u0430\u0440\u0430 \u043d\u0435 \u043f\u043e\u0441\u043b\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438, \u0430 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f:\u0440\u043e\u0431\u043e\u0442 \u0434\u0432\u0438\u0436\u0435\u0442\u0441\u044f      \u2193\u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 lidar      \u2193\u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435?    \u2199           \u2198  \u043d\u0435\u0442            \u0434\u0430   \u2193              \u2193\u0435\u0434\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435    \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430                  \u2193             \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u044b                  \u2193             \u043d\u043e\u0432\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u0440\u0435\u043d\u0438\u044f \u0438 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u043e\u043c.\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u0441\u0442\u0430\u043d\u0435\u0442 \u0443\u0436\u0435 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0437\u0440\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438: \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u044f\u0433\u043e\u0434\u044b, \u043e\u0446\u0435\u043d\u043a\u0430 \u0435\u0451 \u0441\u043f\u0435\u043b\u043e\u0441\u0442\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0434\u043b\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u0430.\u0412 \u0438\u0442\u043e\u0433\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0446\u0438\u043a\u043b:\u041d\u0410\u0412\u0418\u0413\u0410\u0426\u0418\u042f    \u2193\u0440\u043e\u0431\u043e\u0442 \u043f\u0440\u0438\u0435\u0445\u0430\u043b \u043a \u043a\u0443\u0441\u0442\u0443    \u2193\u0422\u0415\u0425\u041d\u0418\u0427\u0415\u0421\u041a\u041e\u0415 \u0417\u0420\u0415\u041d\u0418\u0415    \u2193\u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0441\u043f\u0435\u043b\u0430\u044f \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0430    \u2193\u041c\u0410\u041d\u0418\u041f\u0423\u041b\u042f\u0422\u041e\u0420    \u2193\u044f\u0433\u043e\u0434\u0430 \u0441\u043e\u0431\u0440\u0430\u043d\u0430    \u2193\u041d\u0410\u0412\u0418\u0413\u0410\u0426\u0418\u042f    \u2193\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0440\u0430\u0431\u043e\u0447\u0430\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u2014 \u044d\u0442\u043e \u043d\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0443\u0447\u0435\u0431\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u0430 \u043e\u0434\u0438\u043d \u0438\u0437 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0431\u043e\u0440\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438.\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0430 \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u043a\u043b\u0443\u0431\u043d\u0438\u043a\u0438.\u041f\u0440\u043e\u0435\u043a\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439:module_b_navigation\/\u2502\u251c\u2500\u2500 __init__.py\u251c\u2500\u2500 main.py\u251c\u2500\u2500 graph.py\u251c\u2500\u2500 planner.py\u251c\u2500\u2500 motion_controller.py\u2514\u2500\u2500 obstacle_detector.py\u0422\u0430\u043a\u043e\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u044b, \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e\u0439 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043b\u0438\u0434\u0430\u0440\u0430.graph.py\u041f\u0435\u0440\u0432\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0448\u0435 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 \u0442\u0435\u043f\u043b\u0438\u0446\u044b.import mathclass Graph:    &#171;&#187;&#187;    \u041f\u0440\u043e\u0441\u0442\u0430\u044f \u043a\u0430\u0440\u0442\u0430 \u043f\u043e\u043b\u044f 5&#215;5.    \u041d\u0443\u043c\u0435\u0440\u0430\u0446\u0438\u044f \u043c\u0430\u0440\u043a\u0435\u0440\u043e\u0432:        20 21 22 23 24        15 16 17 18 19        10 11 12 13 14         5  6  7  8  9         0  1  2  3  4    \u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u043c\u0438 \u043c\u0430\u0440\u043a\u0435\u0440\u0430\u043c\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u0440\u0430\u0432\u043d\u044b\u043c 1 \u043c\u0435\u0442\u0440\u0443.    &#171;&#187;&#187;    SIZE = 5    def valid(self, marker):        &#171;&#187;&#187;\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u0442\u0430\u043a\u043e\u0439 \u043c\u0430\u0440\u043a\u0435\u0440.&#187;&#187;&#187;        return 0 &lt;= marker &lt; 25    def position(self, marker):        &#171;&#187;&#187;        \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u0430\u0440\u043a\u0435\u0440\u0430.        \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:        marker = 12        x = 12 % 5  = 2        y = 12 \/\/ 5 = 2        \u0417\u043d\u0430\u0447\u0438\u0442 \u043c\u0430\u0440\u043a\u0435\u0440 12 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0442\u043e\u0447\u043a\u0435 (2, 2).        &#171;&#187;&#187;        x = marker % self.SIZE        y = marker \/\/ self.SIZE        return float(x), float(y)    def neighbors(self, marker, blocked=None):        &#171;&#187;&#187;        \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 \u043a\u043b\u0435\u0442\u043a\u0438.        \u041f\u043e\u0440\u044f\u0434\u043e\u043a:        \u0432\u043f\u0440\u0430\u0432\u043e -&gt; \u0432\u0432\u0435\u0440\u0445 -&gt; \u0432\u043b\u0435\u0432\u043e -&gt; \u0432\u043d\u0438\u0437.        &#171;&#187;&#187;        if blocked is None:            blocked = set()        row = marker \/\/ self.SIZE        col = marker % self.SIZE        result = []        # \u0412\u043f\u0440\u0430\u0432\u043e        if col &lt; self.SIZE &#8212; 1:            result.append(marker + 1)        # \u0412\u0432\u0435\u0440\u0445        if row &lt; self.SIZE &#8212; 1:            result.append(marker + self.SIZE)        # \u0412\u043b\u0435\u0432\u043e        if col &gt; 0:            result.append(marker &#8212; 1)        # \u0412\u043d\u0438\u0437        if row &gt; 0:            result.append(marker &#8212; self.SIZE)        # \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u0437\u0430\u043d\u044f\u0442\u044b\u0435 \u043a\u043b\u0435\u0442\u043a\u0438        return [m for m in result if m not in blocked]    def direction(self, a, b):        &#171;&#187;&#187;        \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u043c\u0438 \u043c\u0430\u0440\u043a\u0435\u0440\u0430\u043c\u0438.        \u041d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432.        &#171;&#187;&#187;        ax, ay = self.position(a)        bx, by = self.position(b)        if bx &gt; ax:            return &#171;RIGHT&#187;        if bx &lt; ax:            return &#171;LEFT&#187;        if by &gt; ay:            return &#171;UP&#187;        if by &lt; ay:            return &#171;DOWN&#187;    def nearest_marker(        self,        x,        y,        max_distance=0.75,        excluded=None    ):        &#171;&#187;&#187;        \u041f\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c \u0442\u043e\u0447\u043a\u0438 \u0438\u0449\u0435\u0442 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043c\u0430\u0440\u043a\u0435\u0440.        \u042d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-494654","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/494654","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=494654"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/494654\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=494654"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=494654"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=494654"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}