Robot Troli 2.0. Bagian 2. Manajemen dalam rviz dan tanpa Elemen kecantikan di rviz

Dalam artikel terakhir tentang kereta otonom rumah 2.0, kami berhasil bekerja pada bagaimana meningkatkan odometer robot anggaran, mencapai pembangunan peta ruang 2d yang dapat diterima menggunakan algoritma slam dan lidar yang terjangkau, memperjelas masalah lain ketika membangun proyek. Kali ini, mari kita lihat bagaimana navigasi otonom bekerja di rviz, apa yang bertanggung jawab, kami akan mengimplementasikan program yang memungkinkan Anda meninggalkan rviz. Pertimbangkan juga beberapa "elemen kecantikan" rviz yang membuat hidup lebih mudah untuk robot ROS.

gambar

Mari kita mulai dengan latihan.


Tugas robot : untuk melakukan perjalanan secara independen dari titik A ke titik B, atau lebih baik, langsung ke beberapa titik B.

Diasumsikan bahwa skrip (node) proyek linorobot di sekitar mana proyek dibangun akan diluncurkan pada robot, dan visualisasi dari apa yang terjadi dan kontrol akan dilakukan. dari PC eksternal, mesin virtual (selanjutnya disebut "PC").

Dalam kasus saya, dari perangkat lunak pada kereta, yang jantungnya adalah raspberry pi 3b single-board, diinstal: Ubuntu 16.04, ROS Kinetic, pada PC: Ubuntu 18.04, ROS Melodic.

Sebelum Anda pergi ke suatu tempat, Anda harus mengatur dimensi robot - panjang dan lebar.
Untuk melakukan ini, seperti yang ditunjukkan pada halaman proyek, Anda harus memasukkan nilai yang sesuai:

roscd linorobot/param/navigation
nano costmap_common_params.yaml

Parameter jejak kaki yang benar:

footprint: [[-x, -y], [-x, y], [x, y], [x, -y]]

di mana x = panjang robot / 2 dan y = lebar / 2
* Idealnya, untuk robot, Anda dapat menggambar model urdf, seperti yang sebelumnya dilakukan dalam proyek kereta robot sebelumnya .

Namun, jika ini tidak dilakukan, navigasi tidak akan banyak menderita, tetapi alih-alih model robot, "sumbu TF" akan melakukan perjalanan di peta. Cara memperbaiki situasi dengan representasi visual robot pada peta sedikit dan pada saat yang sama tidak membuang waktu membangun model urdf, kita akan berbicara lebih jauh.

Kami memulai sebuah lingkungan


Pada robot, jalankan di dua terminal yang berbeda:

roslaunch linorobot bringup.launch
roslaunch linorobot navigate.launch

Di PC, jalankan rviz visual shell:
roscd lino_visualize/rviz
rviz -d navigate.rviz

Jika semuanya berjalan dengan baik, pada PC Anda dapat mengamati lokasi robot di rviz:



Sumbu TF terlihat di rviz, serta opsi Poligon, yang dapat ditambahkan pada panel Display. Poligon - ini hanya ukuran tapak robot yang diperkenalkan di awal, yang memungkinkan Anda untuk melihat dimensi robot. * Sumbu TF terlihat dari sumbu pada gambar: TF-map - map dan TF-base-link - robot itu sendiri, sisa sumbu diredam dalam rviz agar tidak bergabung satu sama lain.

Data dari LIDAR sedikit tidak bertepatan dengan dinding pada peta, robot tidak terlokalisasi.

Jika Anda beralih dari posisi ini, algoritme akan mencoba menyesuaikan, tetapi Anda juga dapat membantu dengan menunjukkan posisi awal secara langsung di rviz menggunakan tombol β€œperkiraan pose 2d”:



Selanjutnya, di jendela visualisasi rviz pada peta, tentukan lokasi awal dan arah robot dengan panah hijau besar - pose awal (Anda dapat melakukan ini berkali-kali):



Setelah menentukan posisi, base_link akan bergerak sedikit relatif ke peta:



Keakuratan absolut dari coincidence dari perbatasan dari lidar dengan peta ketika secara manual menyesuaikan posisi awal tidak dengan posisi awal. diperlukan, algoritma kemudian akan memperbaiki semuanya sendiri.

Sebelum kamu pergi


Setiap kali, masukkan rviz posisi awal, jika di tanah robot mulai dari tempat yang sama pekerjaan begitu-begitu. Oleh karena itu, kami akan menggunakan layanan (ingat bahwa selain topik di ROS ada layanan), saat diakses, ia akan membaca "lokasi robot di peta", maka kami akan menggunakan data ini.

Buat skrip pada PC (tidak masalah di tempat mana)

get_pose.py
#! /usr/bin/env python
import rospy
from std_srvs.srv import Empty, EmptyResponse # Import the service message python classes generated from Empty.srv.
from geometry_msgs.msg import PoseWithCovarianceStamped, Pose
robot_pose = Pose()
def service_callback(request):
    print ("Robot Pose:")
    print (robot_pose)
    return EmptyResponse() # the service Response class, in this case EmptyResponse    
def sub_callback(msg):
    global robot_pose
    robot_pose = msg.pose.pose   
rospy.init_node('service_server') 
my_service = rospy.Service('/get_pose_service', Empty , service_callback) # create the Service called get_pose_service with the defined callback
sub_pose = rospy.Subscriber('/amcl_pose', PoseWithCovarianceStamped, sub_callback)
rospy.spin() # mantain the service open.


Setelah memulai, skrip di terminal tidak menampilkan apa pun dan diam-diam menunggu untuk diakses. Karena di rviz menggunakan antarmuka grafis, kami baru-baru ini mengatur posisi awal robot, Anda dapat merujuk ke skrip baru kami dan mengetahui posisi ini. Tanpa menutup terminal dengan skrip (seperti terminal yang diluncurkan sebelumnya dengan node), di terminal lain kami akan menjalankan:

rosservice call /get_pose_service

Setelah menjalankan permintaan di terminal dengan skrip, get_pose.py akan menampilkan posisi robot:



Simpan indikator ini dan tambahkan ke pengaturan simpul amcl pada robot, sehingga robot mulai dari posisi yang ditentukan setiap kali:

nano linorobot/launch/include/amcl.launch

Menambahkan
parameter
<param name="initial_pose_x" value="0.548767569629"/>
<param name="initial_pose_y" value="0.218281839179"/>
<param name="initial_pose_z" value="0.0"/>
<param name="initial_orientation_z" value="0.128591756735"/>
<param name="initial_orientation_w" value="0.991697615254"/>


Sekarang saat startup, robot akan mulai dari posisi tertentu, dan itu juga tidak perlu diatur secara manual di rviz:



Akhirnya pergi


Mulai ulang perintah untuk robot dan PC yang diberikan di awal dan lihat robot di rviz.

Kami akan menggunakan rviz "Tujuan 2D NAV" untuk mengirim robot ke mana pun yang diinginkan jiwa:



Seperti yang Anda lihat, robot tidak hanya dapat menunjukkan jarak perjalanan, tetapi juga arah gerakan.
Dalam contoh di atas, kami melaju sedikit ke depan, berbalik dan kembali.

Di rviz, kawanan "panah hijau" Amcl yang berkerumun partikel juga terlihat, yang menunjukkan di mana, menurut program, robot berada. Setelah perjalanan, konsentrasi mereka mendekati lokasi sebenarnya dari robot, jumlah total berkurang. Robot berjalan cukup cepat - 0,3 m / s, sehingga program ini membutuhkan lebih banyak waktu untuk melokalisasi robot.

Menavigasi di rviz menggunakan "2D NAV Goal" untuk memahami seberapa jauh dan ke arah mana robot akan melakukan perjalanan nyaman. Tetapi yang lebih nyaman adalah perjalanan tanpa partisipasi operator di rviz.

Karena itu, kami menyoroti di peta tempat-tempat menarik di mana kami akan pergi. Untuk melakukan ini, pindahkan robot ke titik yang diinginkan di peta menggunakan "2D NAV Goal". Pada titik-titik ini ia akan mengakses layanan get_pose.py. Selanjutnya, koordinat semua titik akan ditransfer ke program perjalanan.

Mengapa tidak memindahkan robot di tangan Anda ke tempat menarik? Masalahnya adalah "Amcl particle swarm", algoritma yang membangunnya. Sekalipun robot berada di tempat tujuan, dan posisinya ditentukan secara manual, varian lokasinya akan "disemprotkan" ke area di sekitar tempat tujuan itu sendiri. Karena itu, Anda masih harus pergi.

Mari kita mulai dari titik dengan nama sandi "koridor":



Kami akan menyimpan pose ketika robot berada di titik yang diinginkan menggunakan panggilan ke layanan yang dibuat sebelumnya:

rosservice call /get_pose_service

Berikutnya - "pintu masuk":



Dan titik terakhir - "dapur":



Sekarang saatnya untuk membuat program perjalanan -

MoveTBtoGoalPoints.py
#!/usr/bin/env python
import rospy
import actionlib
# Use the actionlib package for client and server
from move_base_msgs.msg import MoveBaseAction, MoveBaseGoal
# Define Goal Points and orientations for TurtleBot in a list
"""
pose x,y,x; orientation: x,y,z,w
"""
GoalPoints = [ [(5.31514576482, 1.36578380326, 0.0), (0.0, 0.0, -0.498454937648, 0.866915610157)], #corridor
		[(5.77521810772, -1.2464049907, 0.0), (0.0, 0.0,  -0.959487358308, 0.281751680114)], #prixozaya
		[(2.14926455346, -2.7055208156, 0.0), (0.0, 0.0,  -0.99147032254, 0.130332649487)]] #kitchen
# The function assign_goal initializes goal_pose variable as a MoveBaseGoal action type.
def assign_goal(pose):
    goal_pose = MoveBaseGoal()
    goal_pose.target_pose.header.frame_id = 'map'
    goal_pose.target_pose.pose.position.x = pose[0][0]
    goal_pose.target_pose.pose.position.y = pose[0][1]
    goal_pose.target_pose.pose.position.z = pose[0][2]
    goal_pose.target_pose.pose.orientation.x = pose[1][0]
    goal_pose.target_pose.pose.orientation.y = pose[1][1]
    goal_pose.target_pose.pose.orientation.z = pose[1][2]
    goal_pose.target_pose.pose.orientation.w = pose[1][3]
 
    return goal_pose
if __name__ == '__main__':
    rospy.init_node('MoveTBtoGoalPoints')
    # Create a SimpleActionClient of a move_base action type and wait for server.
    client = actionlib.SimpleActionClient('move_base', MoveBaseAction)
    client.wait_for_server()
    # for each goal point in the list, call the action server and move to goal
    for TBpose in GoalPoints:
        TBgoal = assign_goal(TBpose)
        # For each goal point assign pose
        client.send_goal(TBgoal)
        client.wait_for_result()
        # print the results to the screen
        #if(client.get_state() == GoalStatus.SUCCEEDED):
        #    rospy.loginfo("success")
        #else:        
        #   rospy.loginfo("failed")


* Di GoalPoints, kami akan menambahkan koordinat sebelumnya dari titik perjalanan. Ada penjelasan dalam kode di mana urutan parameter: pose x, y, x; orientasi: x, y, z, w - [(5.31514576482, 1.36578380326, 0.0), (0.0, 0.0, -0.498454937648, 0.866915610157)]

Jalankan skrip MoveTBtoGoalPoints.py bersamaan dengan node yang sedang berjalan di robot dan PC, lihat hasilnya:



Seperti yang Anda lihat , robot berhasil melaju ke lorong dan dalam perjalanan ke dapur melihat dirinya di cermin dan macet. Baik dengan larsar saat bertemu dengan cermin, sayangnya begitu.

Apa yang bisa dilakukan?

Dimungkinkan untuk menambahkan titik perantara sebelum dan sesudah cermin, mengurangi kecepatan robot, menempelkan pita buram pada cermin di sepanjang rute.

Tetapi ini adalah langkah selanjutnya, tetapi untuk sekarang kita akan mempertimbangkan tugas bepergian dari titik A ke titik B dengan dan tanpa bantuan rviz selesai. Sekarang, pada prinsipnya, kita tidak perlu PC eksternal, karena skrip perjalanan membawa kita ke titik yang diinginkan di peta.

Tapi jangan terburu-buru untuk menjatuhkan PC bersama dengan rviz, karena proyek linorobot tidak berfungsi dengan benar "di luar kotak", dan Anda perlu "bekerja dengan file" pada tumpukan navigasi.

Inilah saatnya untuk menolak - izinkan saya mengatakan, di mana navigasi otonom, robot melaju dan melangkah maju, menyamping, mundur, dan bahkan melaju ke cermin?

Yah, itu saja, kecuali untuk beberapa detail yang membuat ROS menonjol.

Mari kita lihat detail-detail ini.

Misalkan beberapa warga negara yang tidak bertanggung jawab meninggalkan benda mati di sepanjang jalur robot. Item ini tidak ada di peta yang diberikan kepada robot untuk navigasi:



Apa yang akan terjadi?

Mari kita lihat:



Seperti yang Anda lihat, Lidar melihat hambatan, algoritma menandainya di peta dan memesan jalan memutar.

Akhirnya, tambahkan beberapa keindahan ke rviz


Editor visual rviz memiliki plugin menarik yang tidak diinstal secara default. Penggunaannya dapat menambah banyak poin menarik saat bekerja dengan rviz.

Repositori dengan plugins ada di sini .

Pasang pengaya pada PC kami di lingkungan kami:

roscd; cd ../src;
catkin_create_pkg my_rviz_markers rospy
cd my_rviz_markers/
cd src
git clone https://github.com/jsk-ros-pkg/jsk_visualization
git clone https://github.com/ClementLeBihan/rviz_layer
cd ..
rosdep install --from-paths -y -r src
cd ~/linorobot_ws/
catkin_make

Setelah instalasi di rviz, plugin tambahan akan muncul.

Sekarang, mari kita tambahkan, misalnya, ikon:



Di folder my_rviz_markers / samples, buat skrip:

pictogram_array_objects_demo.py
#!/usr/bin/env python
import rospy
import math
from jsk_rviz_plugins.msg import Pictogram, PictogramArray
from random import random, choice
rospy.init_node("pictogram_object_demo_node")
p = rospy.Publisher("/pictogram_array", PictogramArray,  queue_size=1)

r = rospy.Rate(1)
actions = [Pictogram.JUMP, Pictogram.JUMP_ONCE, Pictogram.ADD, 
           Pictogram.ROTATE_X, Pictogram.ROTATE_Y, Pictogram.ROTATE_Z]
pictograms = ["home","fa-robot"]
object_frames = ["map","base_link"]

while not rospy.is_shutdown():
    
    arr = PictogramArray()
    arr.header.frame_id = "/map"
    arr.header.stamp = rospy.Time.now()
    for index, character in enumerate(pictograms):
        msg = Pictogram()
        msg.header.frame_id = object_frames[index]
        msg.action = actions[2]
        msg.header.stamp = rospy.Time.now()
        msg.pose.position.x = 0
        msg.pose.position.y = 0
        msg.pose.position.z = 0.5
        # It has to be like this to have them vertically orient the icons.
        msg.pose.orientation.w = 0.7
        msg.pose.orientation.x = 0
        msg.pose.orientation.y = -0.7
        msg.pose.orientation.z = 0
        msg.size = 0.5
        msg.color.r = 25 / 255.0
        msg.color.g = 255 / 255.0
        msg.color.b = 240 / 255.0
        msg.color.a = 1.0
        msg.character = character
        arr.pictograms.append(msg)
    p.publish(arr)
    r.sleep()


Mari kita buat itu dapat dieksekusi:

sudo chmod +x pictogram_array_objects_demo.py

Di folder my_rviz_markers / launch, buat peluncuran untuk memulai:

<launch>
  <node pkg="my_rviz_markers" type="pictogram_array_objects_demo.py" name="pictogram_array_objects_demo" </node>
</launch>

Itu dimulai seperti biasa (semua node lain saat ini juga harus bekerja):

roslaunch my_rviz_markers pictogram_array_objects_demo.launch

Letakkan penanda di peta


Marker dapat membantu dalam memahami di mana titik tersebut ada di peta.

Seperti pada contoh sebelumnya, buat skrip di folder my_rviz_markers / samples:

basic_marker.py
#!/usr/bin/env python

import rospy
from visualization_msgs.msg import Marker
from geometry_msgs.msg import Point


class MarkerBasics(object):
    def __init__(self):
        self.marker_objectlisher = rospy.Publisher('/marker_basic', Marker, queue_size=1)
        self.rate = rospy.Rate(1)
        self.init_marker(index=0,z_val=0)
    
    def init_marker(self,index=0, z_val=0):
        self.marker_object = Marker()
        self.marker_object.header.frame_id = "/map"
        self.marker_object.header.stamp    = rospy.get_rostime()
        self.marker_object.ns = "start"
        self.marker_object.id = index
        self.marker_object.type = Marker.SPHERE
        self.marker_object.action = Marker.ADD

        my_point = Point()
        my_point.z = z_val
        #self.marker_object.pose.position = my_point
        self.marker_object.pose.position.x = 5.31514576482
        self.marker_object.pose.position.y = 1.36578380326 
        self.marker_object.pose.orientation.x = 0
        self.marker_object.pose.orientation.y = 0
        self.marker_object.pose.orientation.z = -0.498454937648
        self.marker_object.pose.orientation.w = 0.866915610157
        self.marker_object.scale.x = 0.2
        self.marker_object.scale.y = 0.2
        self.marker_object.scale.z = 0.2
    
        self.marker_object.color.r = 0.0
        self.marker_object.color.g = 0.0
        self.marker_object.color.b = 1.0
        # This has to be, otherwise it will be transparent
        self.marker_object.color.a = 1.0

        # If we want it for ever, 0, otherwise seconds before desapearing
        self.marker_object.lifetime = rospy.Duration(0)
    
    def start(self):
        while not rospy.is_shutdown():
            self.marker_objectlisher.publish(self.marker_object)
            self.rate.sleep()
   
if __name__ == '__main__':
    rospy.init_node('marker_basic_node', anonymous=True)
    markerbasics_object = MarkerBasics()
    try:
        markerbasics_object.start()
    except rospy.ROSInterruptException:
        pass


Di folder my_rviz_markers / launch, buat peluncuran untuk memulai:

basic_marker.launch
<launch>
  <node pkg="my_rviz_markers" type="basic_marker.py" name="basic_marker" />
</launch>


Lari:

roslaunch my_rviz_markers basic_marker.launch

Tambahkan ke rviz:



Tambahkan gambar


Yang akan menunjukkan jarak dan sudut antara dua frame:



Di folder my_rviz_markers / launch, buat peluncuran untuk memulai:

overlay_meny_my.launch overlay_menu_my.launch
<launch>
  <node pkg="my_rviz_markers" type="haro_overlay_complete_demo.py" name="overlay_menu" />
</launch>


Di folder my_rviz_markers / samples, buat skrip:

haro_overlay_complete_demo.py
#!/usr/bin/env python

from jsk_rviz_plugins.msg import OverlayText, OverlayMenu
from std_msgs.msg import ColorRGBA, Float32
import rospy
import math
import random
from geometry_msgs.msg import Twist

class HaroOverlay(object):
    def __init__(self):
        
        self.text_pub = rospy.Publisher("/text_sample", OverlayText, queue_size=1)
        
        self.plot_value_pub = rospy.Publisher("/plot_value_sample", Float32, queue_size=1)
        self.piechart_value_pub = rospy.Publisher("/piechart_value_sample", Float32, queue_size=1)
        self.menu_publisher = rospy.Publisher("/test_menu", OverlayMenu, queue_size=1)
        self.plot_value = 0
        self.piechart_value = 0
        self.max_distance_from_object = 10.0
        
        self.subs = rospy.Subscriber("/haro_base_link_to_person_standing_tf_translation", Twist, self.twist_callback)
        
        self.counter = 0
        self.rate = rospy.Rate(100)
        self.overlaytext = self.update_overlaytext()
        self.menu = self.update_overlay_menu()

    def twist_callback(self, msg):
        self.plot_value = msg.linear.x
        self.piechart_value = msg.angular.z

    def update_overlaytext(self, number=1.23, number2=20):  
        
        text = OverlayText()
        text.width = 200
        text.height = 400
        text.left = 10
        text.top = 10
        text.text_size = 12
        text.line_width = 2
        text.font = "DejaVu Sans Mono"
        text.text = """Distance=  %s.
        Angle=%s.
        Counter = <span style="color: green;">%d.</span>
        """ % (str(number), str(number2) ,self.counter)
        text.fg_color = ColorRGBA(25 / 255.0, 1.0, 240.0 / 255.0, 1.0)
        text.bg_color = ColorRGBA(0.0, 0.0, 0.0, 0.2)
        
        return text
    
    def update_overlay_textonly(self, new_text):
        self.overlaytext.text = new_text


    def update_overlay_menu(self):
        menu = OverlayMenu()
        menu.title = "HaroSystemMode"
        menu.menus = ["Sleep", "Searching", "MovingInCircles","Waiting"]
        
        menu.current_index = self.counter % len(menu.menus)
        return menu
        
    def update_overlay_menu_haro_tf(self):
        menu = OverlayMenu()
        menu.title = "HaroDistanceFromPerson"
        menu.menus = ["FarAway", "CloseBy", "Target", "OtherWayRound"]
        
        fraction = 10.0
        
        if self.piechart_value < (math.pi/fraction):
            if self.plot_value >= self.max_distance_from_object:
                index = 0
            elif self.plot_value >= (self.max_distance_from_object/ fraction) and self.plot_value < self.max_distance_from_object:
                index = 1
            elif self.plot_value < (self.max_distance_from_object/fraction):
                index = 2
            
        else:
            index = 3
            
        menu.current_index = index
            
        return menu

    def start_dummy_demo(self):
        
        while not rospy.is_shutdown():
            self.overlaytext = self.update_overlaytext()
            self.menu = self.update_overlay_menu()
            
            if self.counter % 100 == 0:
                self.menu.action = OverlayMenu.ACTION_CLOSE
            
            self.text_pub.publish(self.overlaytext)
            # If values are very high it autoadjusts so be careful
            self.value_pub.publish(math.cos(self.counter * math.pi * 2 / 1000))
            self.menu_publisher.publish(self.menu)
            
            self.rate.sleep()
            self.counter += 1
    
    def start_harodistance_demo(self):
        
        while not rospy.is_shutdown():
            self.overlaytext = self.update_overlaytext(number=self.plot_value, number2=self.piechart_value)
            self.menu = self.update_overlay_menu_haro_tf()
            
            self.text_pub.publish(self.overlaytext)
            
            self.plot_value_pub.publish(self.plot_value)
            self.piechart_value_pub.publish(self.piechart_value)
            
            self.menu_publisher.publish(self.menu)
            
            self.rate.sleep()
            self.counter += 1
  
  
def dummy_overlay_demo():
    rospy.init_node('distance_overlay_demo_node', anonymous=True)
    haro_overlay_object = HaroOverlay()
    try:
        #haro_overlay_object.start_dummy_demo()
        haro_overlay_object.start_harodistance_demo()
    except rospy.ROSInterruptException:
        pass

if __name__ == '__main__':
    dummy_overlay_demo()


Script kedua adalah

tf_haro_to_object_listener.py
#!/usr/bin/env python
import sys
import rospy
import math
import tf
from geometry_msgs.msg import Twist, Vector3

if __name__ == '__main__':
    rospy.init_node('tf_listener_haro_to_person')

    listener = tf.TransformListener()

    if len(sys.argv) < 3:
        print("usage: tf_haro_to_object_listener.py parent child")
    else:
        follower_model_name = sys.argv[1]
        model_to_be_followed_name = sys.argv[2]
        
        topic_to_publish_name = "/"+str(follower_model_name)+"_to_"+str(model_to_be_followed_name)+"_tf_translation"
        # We will publish a Twist message but it's positional data not speed, just reusing an existing structure.
        tf_translation = rospy.Publisher(topic_to_publish_name, Twist ,queue_size=1)
        
        rate = rospy.Rate(10.0)
        ctrl_c = False
        
        follower_model_frame = "/"+follower_model_name
        model_to_be_followed_frame = "/"+model_to_be_followed_name
        
        def shutdownhook():
            # works better than the rospy.is_shut_down()
            global ctrl_c
            ctrl_c = True

        rospy.on_shutdown(shutdownhook)
        
        while not ctrl_c:
            try:
                (trans,rot) = listener.lookupTransform(follower_model_frame, model_to_be_followed_frame, rospy.Time(0))
                translation_object = Vector3()
                translation_object.x = trans[0]
                translation_object.y = trans[1]
                translation_object.z = trans[2]
                
                angular = math.atan2(translation_object.y, translation_object.x)
                linear = math.sqrt(translation_object.x ** 2 + translation_object.y ** 2)
                cmd = Twist()
                cmd.linear.x = linear
                cmd.angular.z = angular
                tf_translation.publish(cmd)
                
            except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):
                continue
            rate.sleep()


Dimulai seperti ini (diyakini bahwa semua node utama dan rviz sudah berjalan):

roslaunch linorobot overlay_meny_my.launch
python tf_haro_to_object_listener.py base_link map

Kita akan melihat sudut dan jarak frame base_link relatif terhadap peta.

Bersambung.

All Articles