ABONAMENTE VIDEO REDACȚIA
RO
EN
Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 83
Abonament PDF

Introducere în ROS – Robot Operating System

Ovidiu Mățan
Fondator @ Today Software Magazine



PROGRAMARE


Robotic Operating System este un framework specializat în dezvoltarea de aplicații de IoT și în general, de robotică. Avantajele față de o soluție inhouse pentru proiectele de IoT este abstractizarea părții de comunicare între procese, ușurința prin care se pot crea servicii, mecanismele publish - subscriber, parametri globali și multe altele. În acest articol vom aborda conceptele de bază și vom exemplifica comunicarea dintre un SBC (single board computer) și o placă de dezvoltare Arduino.

În articolele anterioare legate de Mașinuța IOT, am arătat cum ne putem transforma în realitate ideile din copilărie, respectiv, să avem o mașinuță teleghidată care să ne recunoască și să interacționeze cu noi. În acele proiecte, am folosit direct implementările în Pyhton și în Arduino pentru a realiza partea de control, comunicare și procesare a datelor. Acum vom simplifica și optimiza întreaga aplicație prin folosirea Robot Operating Systems.

Overview

Dezvoltarea ROS a fost conceput în 2007 de doi doctoranzi care lucrau în laboratorul de robotică de la Universitatea Standford: Eric Berger și Keenan Wyrobek. Ei au început colaborarea cu Scott Hassan, fondatorul Willow Garage unde au și lansat prima versiune. ROS a fost realizat ca un proiect open-source care ajută la dezvoltarea proiectelor de robotică prin re-folosirea diferitelor librării și componente.

Chiar dacă numele ne lasă să credem că vorbim despre un sistem de operare, în realitate, ROS este un framework care rulează pe Linux sau Windows iar pentru MacOS există o variantă experimentală. Bineînțeles că ne putem compila sursele pentru distribuțiile de Linux și platformele noastre hardware. În cazul de față am folosit una dintre ultimele plăci SBC de la NVidia: Jetson Nano care ne oferă un procesor ARM, 4GB RAM și un GPU cu 128 de core-uri CUDA. Instalarea ROS nu a fost lipsită de peripeții și ne face plăcere să vă oferim câteva tips & tricks.

Arhitectura ROS

Reprezintă o rețea distribuită peer to peer unde avem un nod principal: ROS Master care coordonează comunicarea folosind un API bazat pe XMLRPC astfel:

Ref: https://www.researchgate.net/figure/ROS-graph-concepts-a-Core-computation-graph-level-b-messages-publish-and-subscribe_fig2_323709086

Limbajele de programare suportate oficial sunt:

Instalare

Instalarea non-standard pe diferite platforme IoT se poate efectua prin realizarea unui build folosind sursele git. Mai multe detalii pentru instalarea ultimei versiuni ROS, Morenia găsiți aici.

Un aspect important este Catkin, environmentul în care se mențin sursele și pachetele instalate

Turtelism

Turtelsim este un tool realizat pentru învățarea ROS. În continuare, vom vedea folosirea nodurilor ROS în contextul controlării unei broscuțe țestoasă.

A. Pornim nodul master

$ roscore

Vom folosi comanda rosrun pentru a porni un nod:

rosrun  

B. Lansăm nodul turtelism

$ rosrun turtlesim turtlesim_node

D. Controlul broscuței folosind tastele se realizează prin pornirea unui nou nod turtelism care va publica tastele apăsate.

$ rosrun turtlesim turtle_teleop_key

E. Desenarea unui pătrat se realizează prin lansarea unui nod nou

$ rosrun turtlesim draw_square

Hello World

Am văzut cum se lansează nodurile în ROS, vom continua cu o simplă aplicație Echo ce va folosi un Topic pentru trimiterea mesajelor între două noduri folosind mecanismul Publish / Subscriber.

#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def talker():
pub = rospy.Publisher('chatter', String, 
queue_size=10)

rospy.init_node('talker', anonymous=True)
rate = rospy.Rate(10) # 10hz

while not rospy.is_shutdown():
    hello_str = "hello world %s" % rospy.get_time()
    rospy.loginfo(hello_str)
    pub.publish(hello_str)
    rate.sleep()

talker()

Prima linie este destul de importantă și vă poate cauza destule nedumeriri, dacă nu o includeți. Declară fișierul curent unul scris în Python, fără această limie se va considera un fișier bash linux.

Remarcăm definirea nodului Talker cu parametru de anonymous=True, acesta permite execuția nodurilor cu același nume prin adăugarea unui număr aleatoriu în numele acestuia.

Publicarea unui mesaj definește numele topicului, în cazul nostru 'chatter', urmat de tipul mesajului și de dimensiunea cozii de mesaje. Dacă se dorește stocarea doar a valorii curente se poate folosi valoarea 1. Odată definit mesajul se poate aplica metoda publish() care îl va trimite la nodul master, și ulterior la nodurile care s-au înregistrat în topicul nostru.

Un ultim amănunt, metoda rospy.Rate(10) va defini un delay de 1/10 sec în momentul apelării rate.sleep()

import rospy
from std_msgs.msg import String

def callback(data):
rospy.loginfo("I heard %s",data.data)

def listener():
    rospy.init_node('node_name')
    rospy.Subscriber("chatter", String, callback)
    # spin() simply keeps python from exiting until 
    # this node is stopped

    rospy.spin()

Ascultarea mesajelor publicate pe topicul chatter implică definirea unui callback. Metoda rospy.spin() va delega terminarea aplicației nodului ROS, eficientizând primirea / procesarea mesajelor pe durata execuției nodului curent.

Controlul unui nod Arduino

Dacă până acum am văzut bazele unei aplicații ROS, este momentul să vedem ceva concret. Vom conecta la placa noastră Jetson Nano un Arduino folosind un cablu USB. Am văzut într-un articol precedent că nu este atât de simplu să realizăm această comunicare care a implicat inclusiv definirea unui protocol pentru comenzile trimise.

Începem prin instalarea IDE-ului Arduino folosind pașii de aici. Nu uitați să dați un restart la final și de asemenea, să instalați pyserial: Pip install pyserial

Aplicația va avea un nod care va realiza comunicarea cu Arduino și altul care va trimite mesaje către acesta. Codul Arduino este următorul:

#include <ros.h>
#include <std_msgs/Empty.h>
#include <std_msgs/Int32.h>

ros::NodeHandle nh;

void blinkLed(int count){
  for (int i=0;i<count;i++){
   digitalWrite(LED_BUILTIN, HIGH-digitalRead(LED_BUILTIN));   
   // blink the led
   
   delay(100);
  }
}

void messageCb( const std_msgs::Int32& value){
  blinkLed(value.data);
}

void goLeft( const std_msgs::Empty& toggle_msg){
  digitalWrite(LED_BUILTIN, HIGH);   // led is On
}

void goRight( const std_msgs::Empty& toggle_msg){
  digitalWrite(LED_BUILTIN, 0);   // led is Off
}

ros::Subscriber<std_msgs::Int32> sub("toggle_led", &messageCb );

ros::Subscriber<std_msgs::Empty> left("go_left", &goLeft );

ros::Subscriber<std_msgs::Empty> right("go_right", 
   &goRight );

void setup()
{ 
  pinMode(LED_BUILTIN, OUTPUT);
  nh.initNode();
  nh.subscribe(sub);
  nh.subscribe(left);
  nh.subscribe(right);

}

void loop()
{  
  nh.spinOnce();
  delay(1);
}

Pentru aplicația noastră vom avea trei topicuri de mesaje la care ne vom înregistra și vom delega execuția către metode specifice:

Pornim nodul pentru comunicarea cu portul serial:

rosrun rosserial_python serial_node.py /dev/ttyUSB0

Pentru lansarea comenzilor deschideți un nou terminal de unde putem lansa:

rostopic pub toggle_led std_msgs/Int32 20 -once

rostopic pub go_left std_msgs/Empty -once

rostopic pub go_left std_msgs/Empty -once

Bineînțeles că putem publica mesaje pe topicurile Arduino și dintr-un alt nod. Vom scrie un client în Python care va publica în topicul Talker mesajul toggle_led cu parametrul 10. Pentru aceasta deschidem folderul /catkin_ws/src/ unde vom crea un modul nou:

catkin_create arduino_msgs rospy

Adăugăm un folder /script în structura nou creată: /catkin_ws/src/arduino_msgs. Definim un nou fișier talkerArduino.py

#!/usr/bin/env python
import rospy
import time
from std_msgs.msg import Int32
def talker():
    rospy.init_node('talker', anonymous=True)
    pub = rospy.Publisher('toggle_led', Int32, queue_size=1)

    time.sleep(1)
    print "sending message"
    pub.publish(10)
   
talker()

Se creează un nou nod: talker din care vom publica Topicul: toggle_led care are un parametru de tipul Int32. Se remarcă sleepul de o secundă necesar pentru o funcționare corectă. Se pare că fără prezența acestuia mesajul nu ajunge la nodul de Arduino.

Lansăm aplicația:

rosrun arduino_msgs talkerArduino.py

iar pe boardul Arduino vom vedea ledurile pâlpâind, semn că mesajul nostru a ajuns.

Concluzie

Sperăm că v-am deschis apetitul pentru ROS și filozofia acestuia de a simplifica lucrurile. Deși necesită un pic de exercițiu pentru instalare, în special pe sistemele ARM, avantajele refolosirii componentelor existente precum și integrările cu diferite sisteme reprezintă un pas înainte în dezvoltarea oricărui proiect IoT sau de robotică.

LANSAREA NUMĂRULUI 149

Marți, 26 Octombrie, ora 18:00

sediul Cognizant

Facebook Meetup StreamEvent YouTube

NUMĂRUL 147 - Automotive

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects