User Tools

Site Tools


neurali:roscpp_tutorial

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
neurali:roscpp_tutorial [2015/07/24 12:35] – [roscpp] profproneurali:roscpp_tutorial [2020/06/08 22:20] (current) – external edit 127.0.0.1
Line 1: Line 1:
 +< [[neurali:ros]]
  
 +http://wiki.ros.org/roscpp/Overview
 +
 +======roscpp======
 +
 +Prerequisito: [[neurali:ros nodes]]
 +
 +//roscpp// genera automaticamente del codice, non confondere con //rosgcc// che invece è il nome del compilatore.
 +
 +È una libreria utilizzabile dai client dei processi ROS (detti nodi all'interno di package).
 +Questa libreria si usa per i programmi in C++ ma esiste anche la sua equivalente per il python chiamata //rospy//.
 +
 +Quando si scrive un nuovo programma, il programmatore può usare le funzioni di questa libreria per comunicare tramite pubblicazione/sottoscrizione dei cosiddetti //topic// 
 +
 +NOTA: roscpp non supporta comunicazione in rete! Supporta la comunicazione tra node ROS, che possono appartenere allo stesso package, oppure no.
 +
 +Per le comunicazioni in rete (socket) si può
 +  * usare direttamente i socket bsd c,c++,tcp,udp
 +  * sviluppare una nuova libreria ROS per client
 +  * usare [[neurali:ros udpros|UDPROS]]
 +=====Inizializzazione (init e start)=====
 +In realtà //rosccp// è a sua volta un node (appartenente ad un package), come tanti altri.
 +
 +In un programma in cui si vuole usare roscpp per le comunicazioni tra processi, **prima** di chiamare qualsiasi altra funzione di roscpp, si deve eseguire una funzione //%%ros::init()%%// e poi una funzione //%%ros::start()%%//.
 +
 +  - La prima permette anche di rimappare tutti i nomi delle risorse di un node quando questo viene avviato **dalla linea di comando**. Quindi uno stesso nodo può essere avviato più volte usando diverse configurazioni dalla linea di comando (in runtime!) quando si avvia con roslaunch o rosrun. Gli argomenti di roslaunch vengono passati con argc,argv. Inizializzare non vuol dire contattare il master, per approfondimento vedere [[neurali:ros_nodes#roscore]], Approfondimento: link interno [[roscpp_tutorial#dichiarazione_init |alla dichiarazione di ros::init()]] 
 +    * <code>  ros::init();
 +  ros::init(argc, argv, "my_node_name", ros::init_options::AnonymousName);
 +</code>
 +  - Per eseguire uno start, invece, basta creare un manipolatore di nodi
 +    * <code>
 +  ros::NodeHandle nh;             //  ovviamente invoca il costruttore nello stack (non nell'heap)
 +  // ros::start();   // si invoca automaticamente con la creazione del manipolatore
 +  // delete nh;             //  errore, il distruttore si invocherebbe solo se avessi usato new.
 +  // ros::shutdown() // si invoca automaticamente con la distruzione del manipolatore nello stack
 +</code>
 +
 +da leggere? https://courses.cs.washington.edu/courses/cse466/11au/calendar/ros_cc_2_patterns.pdf
 +
 +In realtà la funzione shutdown() può essere chiamata anche manualmente per distruggere il processo.
 +In questo modo si killeranno tutte le sottoscrizioni, pubblicazioni, chiamate di servizi e serventi. 
 +Se si preme CTRL C sulla linea dei comandi, viene intercettato il signal SIGINT e viene automaticamente avviato shutdown()
 +
 +  bool x = ros::ok();  // restituisce true mentre il nodo, o processo, è in esecuzione
 +   ;         // restituisce false quando il nodo è in shutdown...
 +   ;         // è utile dentro while()
 +
 +==== Struttura del package====
 +
 +Oltre a usare le funzioni di inizializzazione il programmatore deve creare anche due cartelle nel package che contiene il suo nodo, affinché esso possa comunicare usando questa libreria.
 +Si tratta delle cartelle "msg" e "srv" di cui si parla qui [[neurali:ros file.msg file.srv]].
 +
 +Codice di esempio: http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29
 +
 +Quando si avvia la compilazione (con [neurali:ros roscpp|roscpp]]), vengono analizzati i file delle cartelle "msg" e "srv" e viene generato automaticamente del codice C++. In questo esempio si comprende che ci potrebbe essere una sovrapposizione tra i nomi dei file nelle due cartelle a causa della sovrapposizione dei loro namespace.
 +
 +  package_name/msg/Prova.msg -> package_name::Prova
 +  package_name/srv/Prova2.srv -> package_name::Prova2
 +
 +Il codice generato automaticamente (prova.c, prova.h) viene salvato in questi percorsi predefiniti
 +
 +  msg_gen/cpp/include/package_name/ 
 +  srv_gen/cpp/include/package_name/ 
 +
 +Codice ottenuto?
 +
 +  #include <std_msgs/String.h>
 +  
 +  std_msgs::String str;
 +
 +----
 +
 +La forward declaration è una dichiarazione anticipata in C++?
 +
 +[[appunti3s:relazioni_tra_classi#associazione]]
 +
 +----
 +
 +La forward declaration è una macro che permette di dichiarare un messaggio e il suo puntatore
 +  * il messaggio è un template di una struct
 +  * il suo puntatore è un tipo shared pointers di [[neurali:boost]] (smart pointers).
 +
 +
 +  ROS_DECLARE_MESSAGE(MyMessage);
 +
 +In python si può usare //typeof// ma non in C++. Per questo motivo è stato necessario introdurre un campo dentro la struttura del messaggio. Il campo si chiama _data_type.
 +
 +----
 +
 +(approfondimento)
 +
 +====dichiarazione_init====
 +
 +<code c>
 +ROSCPP_DECL void init(const M_string& remappings, const std::string& name, uint32_t options = 0);
 +/**
 +* \brief alternate ROS initialization function.
 +*
 +* \param remappings A vector<pair<string, string> > where each one constitutes a name remapping, or one of the special remappings like __name, __master, __ns, etc.
 +* \param name Name of this node. The name must be a base name, ie. it cannot contain namespaces.
 +* \param options [optional] Options to start the node with (a set of bit flags from \ref ros::init_options)
 +* \throws InvalidNodeNameException If the name passed in is not a valid "base" name
 +*/
 +
 +</code>