128
Departament d’Arquitectura i Tecnologia de Computadors Projecte/Treball de Final de Carrera Disseny i Implementaci ´ o d’una Arquitectura de Control per a Robots Aut ` onoms Projecte/Treball de Final de Carrera presentat per Enric Galceran, per obtenir el t´ ıtol de: Enginyer Inform` atic. Directors: Dr. Marc Carreras Sr. Narc´ ıs Palomeras Girona, Setembre de 2010

Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Departament d’Arquitectura i Tecnologia de Computadors

Projecte/Treball de Final de Carrera

Disseny i Implementacio d’una Arquitecturade Control per a Robots Autonoms

Projecte/Treball de Final de Carrera presentat perEnric Galceran,

per obtenir el tıtol de:Enginyer Informatic.

Directors:Dr. Marc CarrerasSr. Narcıs Palomeras

Girona, Setembre de 2010

Page 2: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

ii

Page 3: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Index

1 Introduccio 1

1.1 Antecedents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.2 Motivacio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.3 Estat de l’Art . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.3.1 ROS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.3.2 Player . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.3.3 YARP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.3.4 Orocos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.3.5 CARMEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

1.3.6 Orca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

1.3.7 MOOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

1.3.8 Microsoft Robotics Studio . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1.3.9 MRPT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1.3.10 JAUS Tool Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1.4 Objectius . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1.5 Abast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

1.6 Estructura de la Memoria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2 Planificacio 11

2.1 Context del Projecte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

iii

Page 4: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

iv Index

2.2 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.3 Temporitzacio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.4 Eines de Desenvolupament . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.4.1 Llengua: l’Angles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.4.2 CASE: MagicDraw UML . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.4.3 IDE: Eclipse CDT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.4.4 Control de Versions: CVS . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.4.5 Llenguatge de Programacio: C++ . . . . . . . . . . . . . . . . . . . . . . 15

3 Analisi 17

3.1 Especificacio de Requeriments . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3.1.1 Visio General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3.1.2 Requeriments Funcionals . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3.1.3 Requeriments No Funcionals . . . . . . . . . . . . . . . . . . . . . . . . . 19

3.2 Analisi de Casos d’Us . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3.3 Especificacio Funcional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3.3.1 Visio General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3.3.2 Funcions del Sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

4 Disseny 27

4.1 Arquitectura del Sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.2 Descripcio Detallada del Disseny . . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.2.1 El Modul Core . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

4.2.2 El Modul Networking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

4.2.3 El Modul Data Manipulation . . . . . . . . . . . . . . . . . . . . . . . . 42

4.2.4 El Modul Threading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4.2.5 El Modul I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

Page 5: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Index v

4.2.6 Tot Junt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.3 Discussio de Dissenys Alternatius . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.3.1 Separacio dels conceptes publicador i subscriptor . . . . . . . . . . . . . . 45

4.3.2 Distincio entre DataManips generics i especıfics . . . . . . . . . . . . . . 47

4.4 Disseny de l’estructura dels documents XML . . . . . . . . . . . . . . . . . . . . 47

4.5 Disseny de l’Estructura dels Fitxers de Configuracio . . . . . . . . . . . . . . . . 49

4.5.1 Fitxer de sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

4.5.2 Fitxer de components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

4.6 Disseny del Protocol de Comunicacio XMLoTCP . . . . . . . . . . . . . . . . . 53

4.6.1 Bases del Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

4.6.2 Comportament dinamic . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

4.6.3 Sessio d’Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

4.6.4 Comandes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

5 Implementacio 65

5.1 Guia d’Estil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

5.2 Documentacio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

5.3 Biblioteques de Programacio de Tercers . . . . . . . . . . . . . . . . . . . . . . . 66

5.3.1 Boost C++ Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

5.3.2 POCO C++ Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

5.3.3 OpenCV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

5.3.4 Eigen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

5.3.5 LibSerial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

5.4 Biblioteques del Sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

5.5 Detalls d’Implementacio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

5.5.1 Particularitats del C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

5.5.2 Modul Data Manipulation . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Page 6: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

vi Index

5.5.3 CComponentFactory amb Programacio Generica . . . . . . . . . . . . . . 74

5.5.4 Comunicacio via TCP/IP . . . . . . . . . . . . . . . . . . . . . . . . . . 74

5.5.5 Acces a Ports Serie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

5.5.6 Multiplexador de Ports Serie (Opcio Finalment Descartada) . . . . . . . 75

5.5.7 Enregistrament de Logs . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

5.5.8 Maneig de Memoria amb Smart Pointers . . . . . . . . . . . . . . . . . . 77

5.5.9 Gestio de Callbacks amb Boost.Function i Boost.Bind . . . . . . . . . . . 77

5.5.10 Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

5.5.11 Thread-safe Lazy Singleton amb Boost.Utility . . . . . . . . . . . . . . . 79

6 Reimplementacio de l’Arquitectura O2CA2 i Fase de Proves 81

6.1 Una Ullada al Disseny de l’O2CA2 . . . . . . . . . . . . . . . . . . . . . . . . . . 81

6.1.1 Modul d’Interfıcie del Robot . . . . . . . . . . . . . . . . . . . . . . . . . 82

6.1.2 Modul de Percepcio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

6.1.3 Modul de Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

6.2 Fase de Proves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

6.2.1 Entorn i eines de debugging . . . . . . . . . . . . . . . . . . . . . . . . . 83

6.2.2 Bugs trobats i solucions . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

7 Resultats 87

7.1 Desplegament del Sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

7.1.1 Desplegament al Robot Ictineu . . . . . . . . . . . . . . . . . . . . . . . 87

7.1.2 Desplegament al Robot Sparus . . . . . . . . . . . . . . . . . . . . . . . 88

7.2 Experiments Realitzats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

8 Conclusio 97

8.1 Resum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

8.2 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

Page 7: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Index vii

8.3 Treballs futurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

Bibliografia 100

A Codi Font de la Classe CGenericDataManip 105

Page 8: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

viii Index

Page 9: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Index de figures

2.1 Calendari amb la temporitzacio inicial del projecte. . . . . . . . . . . . . . . . . 13

2.2 Diagrama de Gantt amb les fases de l’elaboracio del software . . . . . . . . . . . 14

3.1 Diagrama de context del sistema. . . . . . . . . . . . . . . . . . . . . . . . . . . 21

4.1 Disseny modular del sistema. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.2 Diagrama de classes amb l’esbos inicial del disseny. . . . . . . . . . . . . . . . . 28

4.3 Diagrama de classes de l’arquitectura dissenyada (vista general). . . . . . . . . . 29

4.4 Diagrama de classes del modul Core. . . . . . . . . . . . . . . . . . . . . . . . . 30

4.5 Diagrama de sequencia: comunicacio via publicacio/subscripcio. . . . . . . . . . 33

4.6 Diagrama de classes de l’AAL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

4.7 Diagrama de classes del logger. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

4.8 Diagrama de sequencia: proces d’inicialitzacio del sistema. . . . . . . . . . . . . 36

4.9 Diagrama de sequencia: exemple de creacio de diferents components i proxies. . 39

4.10 Exemple de comunicacio entre components mitjancant proxies. . . . . . . . . . . 40

4.11 Diagrama de classes del modul Networking. . . . . . . . . . . . . . . . . . . . . . 41

4.12 Diagrama de classes del modul Data Manipulation. . . . . . . . . . . . . . . . . 43

4.13 Diagrama de classes del modul Threading. . . . . . . . . . . . . . . . . . . . . . 44

4.14 Diagrama de classes del modul I/O. . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.15 Diagrama de classes de l’arquitectura dissenyada (vista detallada). . . . . . . . . 46

4.16 Diagrama de classes de la separacio dels conceptes publicador i subscriptor. . . . 47

ix

Page 10: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

x Index de figures

4.17 Diagrama de classes de la distincio manipuladors generics i especıfics. . . . . . . 48

4.18 Diagrama de comunicacio entre estacions durant la inicialitzacio. . . . . . . . . . 55

4.19 Diagrama de comunicacio entre estacions un cop feta la inicialitzacio. . . . . . . 56

5.1 Diagrama de classes de l’acces a ports serie. . . . . . . . . . . . . . . . . . . . . 75

5.2 Diagrama de classes definitiu del logger del sistema. . . . . . . . . . . . . . . . . 76

6.1 Esquema de l’arquitectura O2CA2. . . . . . . . . . . . . . . . . . . . . . . . . . 82

7.1 El robot Ictineu operant a la piscina del CIRS. . . . . . . . . . . . . . . . . . . . 88

7.2 El robot Sparus executant una missio. . . . . . . . . . . . . . . . . . . . . . . . 89

7.3 Entorn de la competicio SAUC-E 2010. . . . . . . . . . . . . . . . . . . . . . . . 90

7.4 Dos membres de l’equip gironı al SAUC-E 2010. . . . . . . . . . . . . . . . . . . 90

7.5 L’equip campio del SAUC-E 2010, format per estudiants de la UdG. . . . . . . . 91

7.6 El robot Sparus realitzant una missio autonoma. . . . . . . . . . . . . . . . . . . 92

7.7 El robot Sparus a punt d’iniciar una trajectoria autonomament a les illes Acores. 93

7.8 El robot Sparus realitzant una trajectoria autonomament. . . . . . . . . . . . . 93

7.9 Trajectoria realitzada per el robot Sparus a les illes Acores. . . . . . . . . . . . . 94

7.10 Model 3D del robot GIRONA 500. . . . . . . . . . . . . . . . . . . . . . . . . . 95

7.11 Metodologia del projecte TRIDENT. . . . . . . . . . . . . . . . . . . . . . . . . 95

Page 11: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Glossari

AAL Architecture Abstraction Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

ACE Adaptive Communiactions Environment

ASIO Asynchronous Input/Output

AUV Autonomous Underwater Vehicle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

CASE Computer-Aided Software Engineering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

CARMEN Carnegie Mellon Robot Navigation Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

CIRS Centre d’Investigacio en Robotica Submarina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

CORBA Common Object Request Broker Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3

CVS Concurrent Versions System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

DOM Document Object Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

DVL Doppler Velocity Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

DSDM Dynamic Systems Development Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

GIRONA Generic Intelligent Robot Operated and Navigated Autonomously . . . . . . . . . . . . . . 99

xi

Page 12: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

xii Index de figures

HTTP Hypertext Transfer Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .26

ICE Internet Communications Environment

IDE Integrated Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

IEEE Institute of Electrical and Electronic Engineers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

JAUS Joint Architecture for Unmanned Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

MRPT Mobile Robot Programming Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

MOOS Mission Oriented Operating Suite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

O2CA2 Object-Oriented Control Architecture for Autonomy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2

ORB Object Request Broker

ROS Robot Operating System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5

ROV Remotely Operated Vehicle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

SAUC-E Student Autonomous Underwater Challenge - Europe . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

SDE Software Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

SLAM Simultaneous Localization and Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

SOA Service-Oriented Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

STL Standard Template Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

TCP Transmission Control Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

Page 13: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Index de figures xiii

UML Unified Modeling Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14

URIS Underwater Intelligent Robotic System

USB Universal Serial Bus

XML eXtensible Markup Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

XMLoTCP eXtensible Markup Language over Transmission Control Protocol . . . . . . . . . . . . 37

uBLAS micro Basic Linear Algebra Subprograms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

UDP User Datagram Protocol

YARP Yet Another Robot Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

Page 14: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,
Page 15: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Agraıments

M’agradaria expressar el meu sincer agraıment a totes les persones que m’han donat suportdurant l’elaboracio d’aquest projecte. Primer de tot, als meus dos directors de projecte; MarcCarreras, per guiar-me sempre pel bon camı, i Narcıs Palomeras, per fer-me tocar sempre depeus a terra.

Vull donar gracies tambe als membres de l’equip gironı del SAUC-E 2010: a l’Arnau, perhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali, pel seu suportincondicional; a en Ricard, en Chee Sing, en Simo i en Sebas, per les seves ganes de fer-ho be;a l’Aggelos, per no deixar mai que s’enfonsi la barca; i a en Xevi Fuster, per haver-me recordatsempre quan era l’hora i perque, finalment, ja estic.

De cap manera puc oblidar-me de la resta de membres del CIRS: en David i en Lluıs, pertenir sempre la solucio idonia a ma; l’Andres, per aportar sempre un plus de felicitat; a l’Emili,per haver-me donat sempre anims; en Pere R. per haver-me ajudat sempre que ha calgut perosobretot a l’hora de fer arqueologia informatica per elaborar els antecedents d’aquest projecte;i la darrera incorporacio a l’equip d’informatics del CIRS, en Pere P.

Dono les gracies tambe a tots els meus amics, pero en especial a en Jordi, en Miquel, l’Adria,l’Aleix, l’Anna, la Laura, l’Aina, l’Albert G., l’Albert P., en Pablo, en Gerard, en Mariano,l’Andreu, en Fel, l’Anna, la Maria Lluısa i la Mireia.

No puc acabar aquests agraıments sense anomenar els meus estimats pares, Jordi i Mari, perhaver estat comprensius amb les meves absencies durant aquests mesos d’intensa feina.

I vull fer una mencio tambe als creadors de l’Spotify, per haver fet mes amenes tantes horesdedicades a aquest projecte.

Moltes gracies a tots i a totes.

xv

Page 16: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Capıtol 1

Introduccio

Ha passat molt temps des que l’escriptor txec Karel Capek va fer servir per primera vegada laparaula robot, a la seva obra de teatre de ciencia ficcio Robots Universals de Rossum estrenadael 1921. Des de les seves primeres implantacions a la industria a principis de la decada dels1960 [Nof, 1999], la robotica ha deixat de formar part nomes de la ciencia ficcio per passar atenir una presencia cada vegada mes notable en el nostre entorn. Tot i que, sovint, encaras’associen al terme robot certes connotacions de quelcom futurista i misterios, un robot esmerament una maquina guiada de manera automatica que pot realitzar tasques per sı sola,gairebe sempre gracies a instruccions programades electronicament, es a dir, software. Quanun robot realitza una tasca senzilla i repetitiva, com per exemple un proces d’empaquetamentconfinat a la cel·la de treball d’una fabrica, el software que el controla pot consistir en nomesunes desenes d’instruccions. No obstant, en camps com l’exploracio espacial o l’exploraciosubmarina, es desitjable que un robot disposi d’un alt grau d’autonomia, es a dir, que siguicapac de respondre a canvis del seu entorn sense assistencia humana. Aquestes activitats esdesenvolupen en entorns que suposen un repte complicat per a un robot: es tracta d’entornsoberts, de relativament grans dimensions i susceptibles de canviar durant l’execucio d’unamissio. Consequentment, aquests requeriments compliquen de manera notable el disseny desoftware que controla robots operant en aquestes circumstancies.

Per fer recerca en robotica sovint es construeixen prototips. Construir-ne un implica tenir ungran nombre de sensors, motors, plaques electroniques i ginys mecanics que cal controlar ambel seu corresponent software, igualment complicat. A mes, aquests robots es fan servir com aplataformes per experimentar amb noves tecniques de navegacio, d’intel·ligencia artificial, etc.Per tant, constantment s’hi estan afegint nous components i fent modificacions als ja existents.Aquesta alta complexitat, unida a la dependencia de dispositius o biblioteques de programaciopoc comuns o obsolets i a l’elevat nombre de desenvolupadors, fa que sovint els projectes dedesenvolupament d’un robot deixin rere seu una pila de software i hardware que no sera utilitzatmai mes i que desapareixera sense deixar rastre [YARP, 2010].

Actualment, executar percepcio visual, acustica i tactil en un robot a la vegada que un controlde motors elaborat en temps real requereix molta potencia de calcul. Tot i que cada anyque passa augmenta la capacitat de calcul de cada computador individual, tambe creixen les

1

Page 17: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

nostres demandes. Per tant, en l’actualitat, la manera mes facil i mes escalable de fer totaquest processament de dades es amb una xarxa de computadors. I aixo planteja el problemade com comunicar de manera transparent i fiable els components del sistema a traves de laxarxa. Existeixen eines pensades per a solucionar-lo, pero, com veurem (seccio 1.3), l’elecciod’una d’aquestes eines implica un alt grau d’acoblament entre el software que es desenvolupai l’eina en si. A mes, quan es vol fer interactuar software desenvolupat amb eines diferents,apareixen les incompatibilitats entre arquitectures, frameworks i middlewares.

A la Universitat de Girona (UdG), el Grup de Visio per Computador i Robotica (VICOROB) farecerca en el camp de la robotica submarina i, a traves del seu Laboratori de Robotica Subma-rina i a les instal·lacions del Centre d’Investigacio en Robotica Submarina (CIRS), construeixrobots submarins, que no queden exempts dels problemes i dificultats acabats de descriure. Persuperar-ho, des de l’inici de l’activitat investigadora del grup s’han elaborat diferents solucionsde software, que han anat quedant obsoletes i fent que se n’haguessin de desenvolupar de noves,amb els costos de temps que aixo comporta.

Aquest projecte preten elaborar el sistema basic (framework) que permeti desenvolupar diversesarquitectures software per a diferents robots d’una manera mes estable i durable, centrant-seen els requeriments del Laboratori de Robotica Submarina. Tot seguit es fa un repas dels ante-cedents d’aquest projecte (seccio 1.1) i es fa un estudi de les eines disponibles per a solucionarels problemes descrits mes amunt (seccio 1.3). A continuacio, es detallen les raons que hanmotivat l’elaboracio d’aquest projecte i el seu abast (seccio 1.2); s’enumeren els seus objectius(seccio 1.4) i es descriu l’estructura d’aquest document (seccio 1.6).

1.1 Antecedents

VICOROB va iniciar la lınia d’investigacio en robotica submarina l’any 1992, quan formava partde la Universitat Politecnica de Catalunya (UPC). Durant els anys 90 es van executar diversosprojectes de recerca de la Comissio Interministerial de Ciencia i Tecnologia i del Ministeride Ciencia i Tecnologia. El primer projecte, TAP 92-0792, iniciat el 1992, consistia en laconstruccio d’un robot submarı del tipus Remotely Operated Vehicle (ROV) , que s’anomenaGarbı, dotat d’uns bracos mecanics per dur a terme tasques en el fons marı. A aquest projecteel seguiren el TAP 95-0425-C02-02 (1995) i el MAR97-0925-C02-02 (1997), relacionats ambmillorar el prototip construıt en el primer projecte.

Durant aquest perıode, el software de control que es desenvolupava consistia en un sol programaque executava totes les tasques en un sol fil d’execucio, sobre la plataforma MS-DOS. Com quees tractava d’un robot teleoperat, la seva complexitat era abordable per una solucio d’aquestescaracterıstiques.

L’any 1999, amb el projecte MAR99-1062-C03-02, s’inicia la construccio d’un segon robot,l’URIS [Batlle et al., 2004]. Aquest era ja un robot submarı autonom, un Autonomous Un-derwater Vehicle (AUV). Per atendre’n els requeriments, es va desenvolupar una nova arqui-tectura de control, anomenada Object-Oriented Control Architecture for Autonomy (O2CA2)

2

Page 18: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

[Ridao et al., 2001]. Es va concebre com una col·leccio d’objectes distribuıts, i es va implemen-tar nativament en C++ sobre el sistema operatiu VxWorks, fent servir eines de desenvolupa-ment d’aquesta plataforma. La implementacio consistia en un conjunt de processos, distribuıtsen diferents nodes d’una xarxa, que executaven una tasca concreta. Per intercomunicar aquestsprocessos, es van seguir algunes de les idees proposades per l’estandard Common Object Re-quest Broker Architecture (CORBA) [Baker, 1997]: partint d’una classe client i d’una classeservidor que ofereix una interfıcie amb un conjunt d’operacions, s’encapsulen els metodes decomunicacio de baix nivell (sockets TCP/IP, pas de missatges amb l’API del sistema operatiu,etc.) en una classe, anomenem-la proxy, que implementa la mateixa interfıcie que el servidor.Quan es crida un metode d’aquesta classe, aquesta envia un missatge a l’objecte servidor ons’especifica l’operacio que cal executar i els seus parametres reals; en rebre el missatge, el ser-vidor executa l’operacio i respon amb el resultat fent servir la seva propia instancia de la classeproxy. De fet, aquesta solucio es efectivament una aplicacio del patro de disseny Proxy, queal seu torn es aplicat pel patro arquitectonic Broker, pedra angular de l’estandard CORBA[Buschmann et al., 1996] [Baker, 1997].

L’any 2002 es va determinar que l’anterior arquitectura havia quedat obsoleta. D’una banda, lacomplexitat de l’anterior solucio feia que qualsevol modificacio fos extremadament costosa i nopogues ser realitzada per persones no avesades a la programacio distribuıda i a la comunicacioper pas de missatges. De l’altra, en el disseny no s’havien tingut en compte els requerimentsde temps real d’un robot, i aixo impedia que el sistema funciones correctament. Per solucionaraquests problemes, es va construir una nova solucio des de zero [Perez, 2002]. L’avanc mesimportant que va aportar aquesta solucio es que solventava els problemes de temps real amb unplanificador de tasques executat sobre el sistema operatiu de temps real QNX. Per encapsularles comunicacions entre objectes, es van aplicar altre cop les idees de CORBA, pero aquest copde manera mes pesada. No obstant, no es seguia l’estandard CORBA al peu de la lletra, sinoque se’n va fer una adaptacio lliure.

El marc de treball desenvolupat el 2002, pero, tenia alguns inconvenients: QNX es un sistemade pagament; no es trobaven disponibles els drivers per a controlar el hardware necessari; elfet que les eines desenvolupades no fossin estandard implicava una corba d’aprenentatge massaabrupta a l’hora d’ampliar i mantenir el sistema. Per aixo, l’any 2005 es va decidir elaborar unanova solucio des de zero [Hernandez, 2005]. Aquesta vegada, per intercomunicar els objectesdistribuıts, es va utilitzar una implementacio estandard de CORBA, anomenada TAO (TheACE ORB), i es va fer el desplegament sobre la plataforma Linux, que oferia respostes alsrequeriments de temps real. Inicialment el sistema es va aplicar per controlar una milloradaversio del robot Garbı, que permetia executar missions autonomes. El 2006 es va construirel robot Ictineu, on tambe es va fer servir aquest software. Aquesta arquitectura ha estatoperativa fins a l’elaboracio d’aquest projecte.

3

Page 19: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

1.2 Motivacio

Com a becari del Laboratori de Robotica Submarina, l’autor d’aquest projecte havia tingutcontacte directe amb la solucio software emprada per fer experiments amb els robots del labo-ratori des de principis de 2008. Durant aquest perıode, es va anar veient que les particularitatsde la plataforma CORBA (utilitzada en la solucio previa a aquest projecte) dificultava moltel desenvolupament de nous components de software per als robots del laboratori: tenia unaescarpada corba d’aprenentatge, era propensa a provocar errors de programacio, i en definitivaobligava a invertir molt temps en desenvolupar software que no produıa directament resultatsexperimentals. D’altra banda, els estudiants que arribaven al Laboratori per a fer-hi practiqueso projectes, havien d’enfrontar-se amb l’elevada corba d’aprenentatge de la plataforma. A mesa mes, hi havia una manca de documentacio, que s’afegia a les dificultats de desenvolupament.

El setembre de 2009 es van realitzar uns experiments al laboratori que van requerir el desen-volupament de nous components de software sobre l’arquitectura de control utilitzada fins almoment. La realitzacio d’aquests experiments es va veure alentida per raons referents a ladificultat d’utilitzar la plataforma CORBA. Tant fou aixı que a partir d’aquell moment es vadeterminar que calia fer servir quelcom que permetes un desenvolupament mes agil del softwareper als robots del laboratori.

A mes, a finals de 2009 es va decidir crear un equip d’estudiants per participar a la competicioeuropea de robotica submarina Student Autonomous Underwater Challenge - Europe (SAUC-E) 2010. Per tant, calia disposar d’una solucio de software que permetes desenvolupar tots elscomponents necessaris per afrontar la competicio.

Per l’experiencia obtinguda al laboratori, es desitjava utilitzar una solucio que no impliquesuna alta dependencia del software que es desenvolupes fent-ne us. D’altra banda, es desitjavaque la solucio fos compatible amb el maxim possible de plataformes de desenvolupament derobots existents, aconseguint d’aquesta manera poder interactuar amb sistemes desenvolupatsper terceres parts.

1.3 Estat de l’Art

Existeixen diverses biblioteques de programacio, frameworks i middlewares pensats per ajudaral desenvolupament de prototips robotics. Tot i aixo, a causa de la mala experiencia amb l’us dela plataforma CORBA [Hernandez, 2005], es va decidir evitar vincular el software del laboratoriamb una solucio concreta.

Aixı, el que es va decidir fer va ser elaborar una solucio propia que s’ajustes plenament alsrequeriments. Per fer-ho, pero, es van estudiar els principals frameworks i middlewares utilitzatsen robotica, per tal d’observar quines caracterıstiques eren les mes interessants de cada solucio.

Tot seguit, doncs, es repassen les principals caracterıstiques de les eines mes utilitzades perelaborar software per a robots.

4

Page 20: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

1.3.1 ROS

Robot Operating System (ROS) es un meta-sistema operatiu de codi obert per a robots [ROS.org, 2010].Proporciona els serveis que poden esperar-se d’un sistema operatiu, com abstraccio del hardwa-re, control de baix nivell de dispositius, implementacio de funcionalitats utilitzades comuna-ment, pas de missatges entre processos i maneig de paquets de software. Proporciona tambeeines i biblioteques per obtenir, compilar, escriure i executar codi sobre multiples computadors.

Elaborar paquets de software sobre ROS implica utilitzar les biblioteques i eines d’aquestaplataforma, generant-se codi font que te un alt nivell d’acoblament amb la plataforma.

1.3.2 Player

Player es un servidor de xarxa per a control de robots. Executant-se en un robot, Player pro-porciona una interfıcie neta i senzilla per als sensors i actuadors del robot sobre la xarxa IP. Unprograma client parla amb Player fent servir un socket TCP, llegint dades des de sensors, escri-vint comandes als actuadors i configurant dispositius sobre la marxa [The Player Project, 2010].Player suporta diversos dispositius hardware. La plataforma original de Player es la famılia derobots ActivMedia Pioneer 2, pero suporta altres robots i molts sensors dels mes comuns. L’ar-quitectura modular de Player fa facil afegir-hi nou hardware, i una comunitat activa d’usuariselabora nous drivers.

L’acoblament dels components elaborats amb Player es tambe elevat, aixı com la corba d’a-prenentatge que cal afrontar per fer us d’aquesta plataforma. La presencia de solucions per arobotica submarina en particular es escassa, i caldria desenvolupar els drivers necessaris per aaquest tipus de vehicles.

1.3.3 YARP

Yet Another Robot Platform (YARP) ofereix interconnexio per a software de robots. Es unconjunt de biblioteques, protocols i eines per mantenir moduls i dispositius netament desaco-blats [YARP, 2010]. Es un middleware no invasiu, sense desig o previsio d’estar en control delsistema que el fa servir.

YARP ofereix un baix acoblament, pero per contra no ofereix mecanismes per a l’execuciosimultania de tasques, deixant a l’usuari la solucio d’aquesta questio. A mes, fa us de formats derepresentacio de dades no estandards que en dificulten la interoperabilitat amb altres sistemes.

1.3.4 Orocos

Orocos es l’acronim d’Open Robot Control Software. Es tracta d’un projecte l’objectiu del quales desenvolupar un framework de proposit general, lliure i modular per a control de robots i

5

Page 21: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

maquines [The Orocos Project, 2010].

Es troba en la fase inicial del seu desenvolupament, tractant-se per tant d’una plataformaexperimental que ofereix poques caracterıstiques als seus usuaris.

1.3.5 CARMEN

Carnegie Mellon Robot Navigation Toolkit (CARMEN) es una col·leccio de software de codiobert per al control de robots mobils. CARMEN es software modular dissenyat per proporcionareines basiques de navegacio com control de sensors, logging, evitament d’obstacles, localitzacio,planificacio de camins i mapping [CARMEN, 2010].

Esta pensada basicament per a robots mobils i orientada a la implementacio d’algorismes, mesque a la flexibilitat d’afegir nous components a la plataforma.

1.3.6 Orca

Orca es un framework de codi obert per desenvolupar sistemes robotics basats en components[Orca, 2010]. Proporciona els mitjans per definir i desenvolupar els blocs constituents que podenorganitzar-se per formar sistemes robotics arbitrariament complexos, des de simples vehiclesfins a xarxes de sensors distribuıts.

Es tracta d’una plataforma que implica un alt acoblament dels components que s’hi desen-volupen. Fa us de protocols de comunicacio no estandards. Solventa sols les questions dedistribucio de components, deixant a l’usuari els temes relacionats amb entrada/sortida i exe-cucio simultania de tasques.

1.3.7 MOOS

Mission Oriented Operating Suite (MOOS) es un middleware en C++ per a recerca en robotica[Newman, 2009]. Consta d’un servidor de noms central, anomenat MOOSDB, on els diversoscomponents que fan us de la plataforma es registren. Aquest servidor permet dur a termecomunicacions de tipus publicacio/subscripcio.

Es una plataforma que permet desenvolupar components agilment, pero implica lligar-los alseu sistema de comunicacio particular. Ofereix flexibilitat en el desenvolupament, pero noproporciona solucions d’acces a dispositius d’entrada/sortida i d’execucio simultania de tasques,deixant la solucio aquestes questions al programador.

6

Page 22: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

1.3.8 Microsoft Robotics Studio

Microsoft Robotics Studio permet a academics, afeccionats i desenvolupadors comercials crearfacilment aplicacions en robotica fent servir un ampli ventall de hardware [Microsoft Corporation, 2010].

Es tracta d’una plataforma privativa i ofereix poca flexibilitat a l’hora de treballar amb prototipsrobotics que utilitzen dispositius per als quals no dona suport, com es el cas del Laboratori deRobotica Submarina.

1.3.9 MRPT

Mobile Robot Programming Toolkit (MRPT) proporciona als desenvolupadors en C++ un com-plet, portable i comprovat conjunt de biblioteques i aplicacions que cobreixen les estructures dedades i algorismes mes comunament usats en moltes arees de la recerca en robotica: localitza-cio, Simultaneous Localization and Mapping (SLAM), visio per computador i motion planning[MRPT, 2010].

Es una plataforma pensava per a fer desenvolupament amb robots mobils, i ofereix poca flexi-bilitat per a treballar amb prototips que requereixen el desenvolupament de controladors per asensors i dispositius no comuns. Deixa tambe a l’usuari la solucio de les questions d’entrada/-sortida i execucio simultania de tasques.

1.3.10 JAUS Tool Set

JAUS Tool Set es un conjunt d’eines de desenvolupament per a la plataforma Joint Architecturefor Unmanned Systems (JAUS). JAUS es una solucio similar a CORBA, ja que implica definirinterfıcies mitjancant un llenguatge especıfic a partir de les quals es genera codi automaticamentque cal refinar per tal d’obtenir els components de software desitjats.

JAUS es una arquitectura formada per un conjunt d’estandards dels quals ja no es fa manteni-ment, i implica un alt grau d’acoblament dels components que s’hi desenvolupen.

1.4 Objectius

Havent revisat els antecedents i descrit el problema que es vol resoldre, tot seguit s’exposen elsobjectius d’aquest projecte.

El proposit del projecte es:

7

Page 23: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

“Desenvolupar una solucio de software que permeti desenvolupar di-verses arquitectures de control per a diferents robots, satisfent els re-queriments del Laboratori de Robotica Submarina. Desplegar aquestasolucio sobre els robots submarins del laboratori”

El proposit d’aquest projecte pot dividir-se en els seguents objectius, mes especıfics:

• Maximitzar el desacoblament. Cal que el software desenvolupat proporcioni el maximdesacoblament possible amb els nous components de software que es desenvolupin allaboratori.

• Facilitat d’us. Cal aconseguir que desenvolupar nous components de software per alsrobots del laboratori sigui senzill, i que permeti als seus desenvolupadors centrar-se en latasca final del component sense haver de fer front a questions de software secundaries.

• Robustesa i fiabilitat. Crear una solucio robusta i fiable que respongui satisfactoriamentdurant l’execucio d’una missio per part d’un robot.

• Participacio al SAUC-E 2010. Participar a la competicio SAUC-E 2010, celebrada elmes de juliol d’enguany, utilitzant el framework desenvolupat en aquest projecte.

• Desplegament. Desplegar el software desenvolupat sobre els robots submarins del La-boratori de Robotica Submarina.

• Documentacio. Elaborar una bona documentacio del projecte.

1.5 Abast

Per acomplir els objectius d’aquest projecte, s’han dut a terme les tasques seguents:

• Planificacio. Contextualitzacio del projecte, seleccio de la metodologia a utilitzar, tem-poritzacio i seleccio de les eines de desenvolupament.

• Analisi. Obtencio i analisi de requeriments per obtenir-ne l’especificacio; a partir d’aquestsrequeriments, elaboracio de l’especificacio funcional, que descriu detalladament com s’hade comportar el sistema.

• Disseny d’una solucio de software que compleixi amb l’especificacio funcional elaborada.

• Implementacio de la solucio dissenyada.

• Fase de proves. Comprovacio que la solucio satisfa els requeriments. Aquesta fase es duraa terme fent una reimplementacio de l’arquitectura de control ja dissenyada al laboratori,anomenada O2CA2.

8

Page 24: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

• Desplegament. Posada en funcionament de tot el software desenvolupat sobre els robotssubmarins Ictineu (ja disponible al laboratori a l’hora d’iniciar aquest projecte) i Sparus(comencat a construır el gener de 2010 per afrontar la competicio SAUC-E). Previsio dedesplegar el software tambe sobre el robot GIRONA 500, que esta previst que es comencia construir el setembre de 2010.

• Afrontar la competicio SAUC-E 2010, celebrada del 28 de juny al 4 de juliol, fent servirel software d’aquest projecte. La solucio desenvolupada ha de permetre elaborar totsels components de software necessaris per afrontar la competicio de robotica submarinaSAUC-E i fer que tot el software estigui llest per les dates que es celebra la competicio.

• Elaborar una bona documentacio que faciliti l’aprenentatge i el desenvolupament de nouscomponents de software i que sigui util i amena per als desenvolupadors.

1.6 Estructura de la Memoria

L’estructura d’aquest document segueix la Guia per als Projectes/Treballs de Final de Carrerade les Enginyeries Informatiques elaborada a la Universitat de Girona el maig de 2010. A mes,s’han seguit els estandards de l’Institute of Electrical and Electronic Engineers (IEEE) sobreespecificacio de requeriments i descripcio del disseny del software.

A continuacio es presenta una breu descripcio de cada capıtol d’aquesta memoria.

• Capıtol 2:, Planificacio. En aquest capıtol es descriu el context on es desenvolupa aquestprojecte, la metodologia emprada, la temporitzacio de les diverses fases i la seleccio deles eines de desenvolupament.

• Capıtol 3:, Analisi. En aquest capıtol es detalla l’especificacio dels requeriments, l’analiside casos d’us dut a terme per a identificar tant els requeriments com les funcions delsistema i, finalment, l’especificacio funcional elaborada.

• Capıtol 4:, Disseny. En aquest capıtol s’explica el disseny arquitectural del sistema, aixıcom es fa una descripcio detallada dels components d’aquest disseny i s’hi discuteixenpossibles alternatives de disseny que han estat descartades. Tot seguit es descriu eldisseny de l’estructura dels documents eXtensible Markup Language (XML) emprats alsistema, l’estructura dels fitxers de configuracio dissenyada i el disseny del protocol decomunicacions via xarxa elaborat per intercomunicar components.

• Capıtol 5:, Implementacio. En aquest capıtol es descriu la guia d’estil utilitzada perelaborar el codi font, el proces de documentacio del codi, les biblioteques de programacioutilitzades i desenvolupades i, finalment, s’hi discuteixen diversos detalls d’implementacioque han tingut especial rellevancia.

• Capıtol 6:, Reimplementacio de l’Arquitectura O2CA2 i Fase de Proves. En aquest capıtols’explica de forma qualitativa el dissenyt de l’arquitectura O2CA2 i es repassa el procesde comprovacio dut a terme i els bugs trobats i solucionats durant les proves.

9

Page 25: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

• Capıtol 7:, Resultats. En aquest capıtol s’exposen els resultats obtinguts fins al momentamb el software elaborat en aquest projecte.

• Capıtol 8:, Conclusio. Aquest capıtol tanca la memoria fent un resum de les tasques dutesterme en el projecte i exposant les conclusions que se’n poden extreure. A continuacioproposa alguns treballs futurs que poden realitzar-se un cop finalitzat aquest projecte.

10

Page 26: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Capıtol 2

Planificacio

En aquest capıtol es descriu el context on es desenvolupa aquest projecte (seccio 2.1), la me-todologia emprada (seccio 2.2), la temporitzacio de les distintes fases (seccio 2.3) i les eines dedesenvolupament utilitzades (seccio 2.4).

2.1 Context del Projecte

Per fer la planificacio d’aquest projecte ha calgut tenir en compte certes restriccions de recursosi temps. Inicialment, es va decidir iniciar el desenvolupament del nou software i comencar aprovar-lo amb el robot Ictineu, del qual ja es disposava al laboratori. Es va determinar queamb l’Ictineu calia poder comencar a fer experiments fent servir el nou software l’abril de 2010.

A finals de 2009, va decidir-se crear un equip per prendre part en la competicio SAUC-E 2010i construir un nou robot per fer-ho, i per tant va caler ajustar la planificacio tenint en compteque el software havia d’estar llest per la competicio (celebrada el juliol de 2010) i que caliaprovar-lo en el nou robot.

D’altra banda, a mida que s’anava desenvolupant aquest projecte, l’equip d’informatics delCIRS i l’equip d’estudiants que afrontaria el SAUC-E, dels quals l’autor d’aquest projecteen forma part, anava elaborant paral·lelament diversos components de software basats en elframework que s’anava desenvolupant. Per tant, calia ajustar el proces de desenvolupament persatisfer els requeriments que anaven sorgint a l’hora de desenvolupar aquests altres components.

2.2 Metodologia

Donat que al Laboratori de Robotica Submarina hi ha diversos projectes de recerca en marxai varis estudiants que duen a terme les seves tesis doctorals fent experiments amb els robots,calia obtenir un software capac d’executar-se en un robot i controlar-lo i extreure’n dades el

11

Page 27: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

mes rapid possible. Per tant, calia una metodologia que dones resultats des del primer moment,descartant aixı les classiques metodologies pesades de desenvolupament de software.

Per aixo es va fer recerca sobre les metodologies anomenades agils. Aixı, es va trobar undocument anomenat Agile Manifesto [Beck et al., 2001], elaborat l’abril del 2001 per un grupd’experts enginyers del software van voler donar un impuls al que des de llavors s’anomenadesenvolupament agil de software. El manifest diu aixı:

“Estem descobrint millors maneres de desenvolupar software tant per la nostrapropia experiencia com ajudant els altres. A traves d’aquesta feina hem apres avalorar:

• Els individus i les interaccions sobre els processos i les eines

• Software que funciona sobre documentacio exhaustiva

• Col·laboracio dels clients sobre negociacio de contracte

• Respondre als canvis sobre seguir un pla

Aixo es, tot i que valorem els ıtems de la dreta, nosaltres valorem mes els de l’es-querra.”

Aquest manifest fou signat pels impulsors de la majoria de metodologies lleugeres: ExtremeProgramming, Scrum, Dynamic Systems Development Method (DSDM), Adaptive Software De-velopment, Crystal, Feature Driven Development i Pragmatic Programming. De fet, totes lesmetodologies lleugeres tenen molts punts en comu. Per tant, mes que invertir temps en discutirquina d’aquestes metodologies utilitzar, es va decidir aplicar les idees de l’Agile Manifesto.

2.3 Temporitzacio

Havent decidit que calia elaborar una nova solucio de software per als robots del laboratori, esva dur a terme una planificacio inicial. El calendari de la figura 2.1 mostra aquesta planificacio,on pot identificar-s’hi el proces de desenvolupament del software fet en aquest projecte aixı comla resta de tasques i esdeveniments que hi han tingut efecte.

La figura 2.2 mostra un diagrama de Gantt amb el proces de desenvolupament del softwared’aquest projecte que efectivament s’ha dut a terme. Els moduls i els esdeveniments que s’hirepresenten es discutiran mes endavant als capıtols 4 i 5.

2.4 Eines de Desenvolupament

Tot seguit es fa un repas de les eines utilitzades per desenvolupar aquest projecte i de lescaracterıstiques que han determinat la decisio de fer-les servir.

12

Page 28: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Setembre  2009  

dl   dt   dc   dj   dv   ds   dg  

31   1   2   3   4   5   6  

7   8   9   10   11   12   13  

14   15   16   17   18   19   20  

21   22   23   24   25   26   27  

28   29   30   1   2   3   4  

Octubre  2009  

dl   dt   dc   dj   dv   ds   dg  

28   29   30   1   2   3   4  

5   6   7   8   9   10   11  

12   13   14   15   16   17   18  

19   20   21   22   23   24   25  

26   27   28   29   30   31   1  

Novembre  2009  

dl   dt   dc   dj   dv   ds   dg  

27   27   28   29   30   31   1  

2   3   4   5   6   7   8  

9   10   11   12   13   14   15  

16   17   18   19   20   21   22  

23   24   25   26   27   28   29  

Desembre  2009  

dl   dt   dc   dj   dv   ds   dg  

30   1   2   3   4   5   6  

7   8   9   10   11   12   13  

14   15   16   17   18   19   20  

21   22   23   24   25   26   27  

28   29   30   31   1   2   3  

Gener  2010  

dl   dt   dc   dj   dv   ds   dg  

28   29   30   31   1   2   3  

4   5   6   7   8   9   10  

11   12   13   14   15   16   17  

18   19   20   21   22   23   24  

25   26   27   28   29   30   31  

Febrer  2010  

dl   dt   dc   dj   dv   ds   dg  

1   2   3   4   5   6   7  

8   9   10   11   12   13   14  

15   16   17   18   19   20   21  

22   23   24   25   26   27   28  

1   2   3   4   5   6   7  

Abril  2010  

dl   dt   dc   dj   dv   ds   dg  

29   30   31   1   2   3   4  

5   6   7   8   9   10   11  

12   13   14   15   16   17   18  

19   20   21   22   23   24   25  

26   27   28   29   30   1   2  

Maig  2010  

dl   dt   dc   dj   dv   ds   dg  

26   27   28   29   30   1   2  

3   4   5   6   7   8   9  

10   11   12   13   14   15   16  

17   18   19   20   21   22   23  

24   25   26   27   28   29   30  

Juny  2010  

dl   dt   dc   dj   dv   ds   dg  

31   1   2   3   4   5   6  

7   8   9   10   11   12   13  

14   15   16   17   18   19   20  

21   22   23   24   25   26   27  

28   29   30   1   2   3   4  

Juliol  2010  

dl   dt   dc   dj   dv   ds   dg  

28   29   30   1   2   3   4  

5   6   7   8   9   10   11  

12   13   14   15   16   17   18  

19   20   21   22   23   24   25  

26   27   28   29   30   31   1  

Agost  2010  

dl   dt   dc   dj   dv   ds   dg  

26   27   28   29   30   31   1  

2   3   4   5   6   7   8  

9   10   11   12   13   14   15  

16   17   18   19   20   21   22  

23   24   25   26   27   28   29  

Març  2010  

dl   dt   dc   dj   dv   ds   dg  

1   2   3   4   5   6   7  

8   9   10   11   12   13   14  

15   16   17   18   19   20   21  

22   23   24   25   26   27   28  

29   30   31   1   2   3   4  

Setembre  2010  

dl   dt   dc   dj   dv   ds   dg  

30   31   1   2   3   4   5  

6   7   8   9   10   11   12  

13   14   15   16   17   18   19  

20   21   22   23   24   25   26  

27   28   29   30   1   2   3  

Entrega de la memòria

Reunió inicial

Desenvolupament del software

Construcció del robot SPARUS

Proves amb el robot Ictineu

Proves amb el robot SPARUS

Competició SAUC-E

Elaboració de la memòria

Reimplementació de l’O2CA2

Figura 2.1: Calendari amb la temporitzacio inicial del projecte.

13

Page 29: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Parts  del  so+ware  

Sep  2009  

Oct  2009  

Nov  2009  

Des  2009  

Gen  2010  

Feb  2010  

Mar  2010  

Abr  2010  

Maig  2010  

Jun  2010  

Jul  2010  

Ago  2010  

Set  2010  

Nucli  

Accés  a  disposi4us  d’entrada/sor4da  

Manipuladors  de  dades  XML  

Comunicacions  via  xarxa  

Mul4threading  

Reimplementació amb Boost Implementació inicial Detecció problema

Implementació inicial Reimplementació per facilitar-ne l’ús

Figura 2.2: Diagrama de Gantt amb l’elaboracio que efectivament s’ha fet de les diferents partsdel software desenvolupat.

2.4.1 Llengua: l’Angles

Tant el disseny com la implementacio del projecte (incloent-hi la documentacio del codi) s’hanelaborat en angles, ja que es la llengua vehicular dels membres del CIRS aixı com dels estudiantsque hi fan practiques o experiments per les seves tesis doctorals.

2.4.2 CASE: MagicDraw UML

MagicDraw UML es una eina Computer-Aided Software Engineering (CASE) desenvolupadaper No Magic, Inc. Suporta l’estandard Unified Modeling Language (UML) 2.3, enginyeria decodi per a diversos llenguatges de programacio (Java, C++, C#) i modelat de dades. L’einas’integra be tant amb el llenguatge de programacio utilitzat com amb l’Integrated DevelopmentEnvironment (IDE).

2.4.3 IDE: Eclipse CDT

L’Eclipse CDT es l’IDE per a C++ del Software Development Environment (SDE) Eclipse,i proporciona tot el que s’espera d’un IDE modern: analisi sintactic sobre la marxa, controlde versions, debugging i compilacions en un clic, caracterıstica crucial per a un millor codi[Spolsky, 2000b].

14

Page 30: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

2.4.4 Control de Versions: CVS

La xarxa de suport per a projectes de coid obert SourceForge ofereix un servei de ConcurrentVersions System (CVS) gratuıt als seus usuaris, que permet fer servir els avantatges de CVSsense haver-se de preocupar de l’administracio del servei. A mes, l’Eclipse permet fer lessincronitzacions molt facilment mitjancant un plug-in que ja porta incorporat.

Hi ha alternatives mes modernes al CVS que ofereixen mes caracterıstiques, com Subversion oMercurial, que fa control de versions distribuıt. Pero CVS es facil de fer servir des de l’Eclipsei satisfa plenament les necessitats del projecte.

2.4.5 Llenguatge de Programacio: C++

C++ es un llenguatge de programacio que suporta la programacio orientada a objectes, clau pera desenvolupar un sistema de software complex [Cline et al., 1999]. Bjarne Stroustrup, creadordel llenguatge, descriu a The Design and Evolution of C++ alguns criteris de disseny que fande C++ la millor opcio per desenvolupar aquest projecte:

• C++ esta dissenyat per suportar directament i extensiva multiples estils de programa-cio (procedural programming, abstraccio de dades, programacio orientada a objectes iprogramacio generica).

• C++ esta dissenyat per donar sempre al programador l’oportunitat d’escollir, fins i totsi aixo fa possible que el programador esculli incorrectament.

• C++ no provoca overhead per caracterıstiques que no es fan servir (el principi d’overheadzero).

Per tant, en el context d’aquest projecte, C++ proporciona:

• Flexibilitat per poder fer les coses de moltes maneres diferents: com mes opcions hi ha,mes possibilitats de trobar una millor manera de programar un fragment de codi.

• Programes que s’executen el mes rapid possible. Un punt clau en sistemes robotics, quetıpicament requereixen caracterıstiques de temps real.

15

Page 31: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

16

Page 32: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Capıtol 3

Analisi

En aquest capıtol es detalla l’especificacio dels requeriments (seccio 3.1), l’analisi de casos d’usdut a terme per a identificar tant els requeriments com les funcions del sistema (seccio 3.2) i,finalment, l’especificacio funcional elaborada (seccio 3.3).

3.1 Especificacio de Requeriments

Un cop feta la planificacio del projecte, cal descriure el domini del problema que es vol re-soldre, especificant quins son els requeriments del sistema que es vol construir. Per fer-ho,s’ha seguit com a guia l’estandard IEEE 830 [IEEE Computer Society, 1998], sobre practiquesrecomanades per a l’especificacio de requeriments del software.

3.1.1 Visio General

A grans trets, es vol crear una base on constuir software per a robots. Software que consti decomponents individuals capacos d’interactuar facilment entre ells i amb el hardware del robotpero que estiguin netament desacoblats els uns dels altres. I es vol que el programador d’aquestscomponents no s’hagi de preocupar per les tasques mes tedioses i repetitives d’aquests sistemesPer aixo, tindrem en compte l’experiencia previa (vegeu seccio 1.1) i les solucions estudiades al’estat de l’art (seccio 1.3).

Els requeriments poden ser funcionals o no funcionals. Els requeriments funcionals descriuencom s’ha de comportar el sistema, el que el sistema ha de fer:

• Tot allo que pot ser capturat en un cas d’us.

• Tot allo que pot ser analitzat dibuixant diagrames de sequencia, diagrames d’estats, etc.

17

Page 33: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Els requeriments funcionals probablement acabaran corresponent a trocos concrets d’una apli-cacio. Per contra, els requeriments no funcionals son restriccions globals en un sistema desoftware, sovint mes relacionades amb la gestio empresarial que no pas amb els tecnicismesinformatics:

• Restriccions de costos de desenvolupament, de costos de funcionament, de rendiment, defiabilitat, portabilitat, etc.

• En angles, sovint conegudes com les ilities (portability, reliability, etc.).

Habitualment no poden implementar-se en un modul concret de l’aplicacio, sino que afecten atot el conjunt.

3.1.2 Requeriments Funcionals

El sistema ha de:

1. Ser una plataforma on poder construir els diversos components necessaris per controlarun robot.

2. Ser el menys invasiu possible: els components construıts han de poder tenir poc acobla-ment amb el sistema i entre ells mateixos.

3. Permetre afegir-hi nous components de manera facil.

4. Permetre habilitar i deshabilitar els seus components.

(a) Cal poder seleccionar quins components seran habilitats quan el sistema s’inicialitza.

(b) Cal poder habilitar i deshabilitar components en temps d’execucio.

5. Permetre l’execucio simultania de les tasques que duen a terme els seus components.

6. Permetre als seus components intercanviar informacio.

7. Permetre als seus components indicar que un esdeveniment determinat ha succeıt.

8. Permetre als seus components desar informacio de configuracio de manera persistent.

9. Permetre als seus components desar logs.

10. Permetre que els seus components estiguin distribuıts en diferents nodes d’una xarxa decomputadors.

(a) Aquest requeriment ha de ser transparent des del punt de vista de l’intercanvi d’in-formacio entre components.

(b) Cal que la informacio persistent estigui centralitzada en un sol node de la xarxa.

18

Page 34: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

11. Proporcionar una interfıcie als seus components per accedir a dispositius d’entrada isortida (framegrabbers, ports serie, etc).

12. Poder comunicar-se amb sistemes d’informacio externs.

(a) Cal que el sistema ofereixi una interfıcie de comunicacio propia, que permeti a sis-temes externs obtenir informacio del sistema i executar-hi operacions.

(b) Cal que es puguin afegir facilment extensions al sistema perque es pugui comunicarutilitzant sistemes de comunicacio ja existents.

3.1.3 Requeriments No Funcionals

La llista de requeriments no funcionals s’ha elaborat seguint el criteri de McCall [van Vliet, 2000].

Operacio del Producte

Usabilitat:

• Tant el sistema de software com el hardware on s’executa han de garantir el seu correctefuncionament des de l’inicialitzacio del sistema fins la fi d’una missio.

Integritat:

• Es suposa que el sistema opera en una xarxa confinada o protegida per un tallafocs. Elcontrol i auditoria d’acces no son un requeriment.

Temps:

• El sistema ha de garantir l’execucio de tasques en temps real.

Correctesa:

• L’execucio del sistema ha de ser tracable.

Fiabilitat:

• Les sortides del sistema han de tenir una precisio equiparable a l’epsilon de la maquina ∗.

∗L’epsilon de la maquina dona una fita superior de l’error relatiu causat per l’arrodoniment en aritmetica decoma flotant. Depen del tipus de nombres en coma flotant utilitzats i del tipus d’arrodoniment. Per exemple,aquest valor es 1.11e− 16 per al format de doble precisio de l’estandard IEEE 754.

19

Page 35: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

• Les sortides del sistema s’han d’actualitzar en temps real, dins els requeriments de cadatasca individual.

• El sistema ha de garantir la seva correcta execucio des del principi fins al final d’unamissio.

Revisio del Producte

Manteniment, comprovabilitat i flexibilitat:

• El sistema ha de ser el mes senzill possible de desenvolupar.

• Ha de ser facil d’afegir noves caracterıstiques al sistema.

• Els fluxos de comunicacio entre components han de ser facilment tracables.

Transicio del Producte

Portabilitat:

• El sistema ha de ser compatible amb el maxim de plataformes possible.

Interoperabilitat:

• El sistema ha de fer servir sistemes de comunicacio el mes comuns possible.

• El sistema ha de fer servir sistemes de representacio de dades el mes comuns possible.

3.2 Analisi de Casos d’Us

L’analisi de casos d’us ha ajudat tant a identificar els requeriments del sistema com les sevesfuncions. La figura 3.1 mostra el diagrama de casos d’us de context del sistema, on podemidentificar els diferents casos d’us i els dos actors: el propi sistema i els components que l’uti-litzen.

3.3 Especificacio Funcional

Un cop tenim descrit el domini del problema amb l’especificacio de requeriments, cal descriureel domini de la solucio. L’especificacio funcional descriu completament com funcionara un

20

Page 36: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Figura 3.1: Diagrama de context del sistema.

21

Page 37: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

producte des del punt de vista de l’usuari [Spolsky, 2000a]. Tot seguit es dona una visio generalde les funcions del sistema (subseccio 3.3.1). A continuacio es detalla punt a punt cada funcio(3.3.2).

3.3.1 Visio General

A partir de l’analisi de requeriments podem entendre que el sistema haura de constar de lesseguents funcions:

• Gestio de components (afegir-ne de nous, habilitar-los/deshabilitar-los).

• Execucio simultania de tasques.

• Comunicacio entre components.

• Comunicacio d’esdeveniments.

• Gestio de configuracions.

• Enregistrament de logs.

• Distribucio dels components.

• Centralitzacio de la informacio persistent en un sol node.

• Acces a dispositius d’entrada/sortida.

• Comunicacio amb sistemes externs.

3.3.2 Funcions del Sistema

Gestio de Components

• Tots els components han de tenir un nom que els identifiqui i que ha de ser constantdurant una execucio del sistema.

• Cal poder especificar quins components intervindran en un execucio del sistema en par-ticular.

• Els components s’han de poder habilitar/deshabilitar.

• Cal poder canviar la configuracio d’un component sobre la marxa, en qualsevol momenten temps d’execucio.

22

Page 38: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Execucio Simultania de Tasques

• Els components han de poder executar tasques al mateix temps en fils d’execucio (threads)diferents. Per exemple, un sensor de teclat pot llegir les tecles premudes cada 20 ms, i almateix temps mostrar per pantalla els codis d’aquestes tecles cada 500 ms o cada segon.

• S’han de poder crear fils d’execucio periodics, que s’executen cada cert temps, i no pe-riodics, que nomes s’executen un cop.

• S’han de poder crear tants fils com permeti el sistema operatiu.

Comunicacio Entre Components

• Totes les comunicacions entre components consistiran en documents XML (sempre que si-gui viable, vegeu el seguent punt). D’aquesta manera s’eviten els maldecaps que comportadefinir representacions per a tipus de dades enters, reals, booleans, etc., serialitzar-los enl’ordre de bytes correcte, enviar-les per la xarxa i deserialitzar-les.

• Les comunicacions podran contenir dades binaries. Hi ha casos on la codificacio en XMLde les dades no es viable a causa de l’overhead que suposa, per exemple quan es vol enviaruna imatge. En aquest cas es podria enviar una descripcio de la imatge en XML (alcada,amplada, profunditat de color) i la representacio en bytes de la imatge.

• Els components es poden comunicar amb dos estils diferents:

– Publish-Subscribe: un component publicador publica dades sense saber qui en son elscomponents destinataris. Aquests destinataris (subscriptors) s’han subscrit previamental publicador, i en reben les dades.

– Orientat a servei: un component fa una peticio de servei a un altre component, queja coneix. Aquest processa la peticio i li torna una resposta al primer.

• Si els components emissor i receptor es troben a la mateixa estacio (i.e. comparteixen unmateix espai de memoria, vegeu mes avall Distribucio dels Components), es comunicaranfent servir pas de missatges entre objectes convencional.

• Si el component emissor es troba en una estacio diferent que el receptor o viceversa, lacomunicacio es fara via xarxa fent servir un protocol de comunicacio.

– El sistema proporcionara un protocol propi basat en connexions Transmission Con-trol Protocol (TCP) i missatges en XML, que caldra dissenyar.

– El sistema haura de poder comunicar-se amb components mitjancant sistemes decomunicacio externs, com per exemple ROS o MOOS.

23

Page 39: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Comunicacio d’Esdeveniments

• El sistema ha de constar d’un modul anomenat Architecture Abstraction Layer (AAL),que s’encarregara de les funcions de comunicacio d’esdeveniments i d’abstreure les accionsque pot fer el sistema en primitives (vegeu [Palomeras et al., 2008]).

• Qualsevol component del sistema ha de poder notificar que un esdeveniment ha succeıt aun sistema extern mitjancant l’AAL. Aixo esta pensat per interoperar amb sistemes decontrol de missio basats en esdeveniments.

• El sistema ha de poder rebre la reaccio a aquests esdeveniments des d’un sistema externmitjancant l’AAL. Tıpicament, un sistema de control de missio extern haura rebut l’es-deveniment, i enviara una reaccio de tornada que caldra despatxar cap als componentsoportuns.

Gestio de Configuracions

• La informacio de configuracio es guardara en format XML.

• Hi haura dos fitxers de configuracio: un de sistema i un amb la configuracio de tots elscomponents (en endavant, fitxer de components).

• Al fitxer de sistema s’hi ha d’especificar:

– El format amb el qual es guarden els logs de sistema i els logs de missio.

– Com es distribueixen els components: quines estacions hi ha al sistema i quinscomponents hi ha a cada estacio (indicant els noms dels components que s’executenen una estacio determinada). Vegeu mes avall Distribucio dels Components.

– Quins dispositius d’entrada/sortida ofereix cada estacio.

– Les subscripcions: quins components estan subscrits a quins altres.

• Tots els components han de poder llegir la informacio del fitxer de components (tant lareferent a ells com a qualsevol altre component).

• Tots els components han de poder desar i actualitzar la seva configuracio (nomes la seva)al fitxer de components.

Enregistrament de Logs

• Hi haura una interfıcie que permeti desar logs.

• La interfıcie per desar logs ha de poder-se fer servir des de tots els components.

24

Page 40: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

• Els logs es desaran en fitxers de text, lınia a lınia. Cada lınia representara la fila d’unamatriu, i cada fila tindra el mateix nombre de columnes. Aixı podran tractar-se facilmentamb aplicacions de tractament de logs (com Matlab), que solen poder operar amb aquestformat.

• Hi haura dos tipus de logs : logs de missio i logs de sistema. Els logs de missio es refereixena dades que tenen rellevancia en l’execucio de la missio; per exemple, el componentnavegador pot desar la posicio, o el component bruixola pot desar l’orientacio respecte elnord. Els logs de sistema informen de coses que afecten el sistema en si: errors, estat del’execucio d’una tasca (util per a fer traces), estat del vehicle, etc.

• Els logs de missio es desaran en fitxers diferents, un per a cada component.

• Els logs de sistema es desaran tots en un mateix fitxer.

• Cal poder definir (a la configuracio de sistema) un format per a les les lınies dels logs demissio i un altre per a les dels logs de sistema. Aquest format pot consistir, per exemple,en afegir una marca de temps al principi de la lınia.

• Cal poder distingir diferents sessions de log en una mateixa missio. Per exemple, si uncomponent ha canviat la seva configuracio es desitjable que hi hagi una sessio abans delcanvi i una despres.

• Es generara un fitxer de log per cada component i per cada sessio. El nom de cada fitxervindra donat pel nom del component que l’ha generat, seguit de la marca de temps en ques’ha iniciat el log, seguida del nombre de sessio i seguit de l’extensio .log. Per exemple,suposem que al sistema hi ha dos components, component A i component B, i en unaexecucio el component A inicia dues sessions i el component B nomes una. Es generarienels seguents fitxers:

– component A 2010-09-21-10-00-00-345 1.log

– component A 2010-09-21-10-00-00-345 2.log

– component B 2010-09-21-10-00-00-345 1.log

• Els fitxers de log es desaran en un directori especificat per l’usuari al fitxer de configuraciode sistema. Per cada execucio del sistema, es creara un nou directori dins aquest quecontindra tots els fitxers de log d’aquella execucio. El nom d’aquest directori incloura lamarca de temps amb l’instant de creacio del directori.

• Cada fitxer de log corresponent a una sessio ha de comencar amb unes lınies distingidesper un sımbol o sımbols de comentari (una capcalera), que podran indicar a que corresponcada columna del log, a quina missio correspon o qualsevol altra cosa relativa a la sessio.El(s) sımbol(s) de comentari s’especificaran al fitxer de configuracio de sistema.

• L’inici del log es considera una nova sessio, i per tant ha d’incloure tambe la capcalera.

25

Page 41: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Distribucio dels Components

• Els components es distribuiran en diferents estacions. A cada node de la xarxa on s’exe-cuta el sistema hi haura com a mınim una estacio. Cada estacio aglutina un conjunt decomponents, i els permet comunicar-se amb components d’altres estacions.

Centralitzacio de la Informacio Persistent

• La informacio persistent (i.e. els fitxers de configuracio) nomes seran emmagatzemats peruna unica estacio.

• La resta d’estacions gestionaran els fitxers fent peticions a l’estacio que els emmagatzema.

Acces a Dispositius d’Entrada/Sortida

• Cada estacio ofereix als seus components acces als dispositius d’entrada/sortida que s’-hagin especificat al fitxer de configuracio (vegeu mes amunt Gestio de Configuracions).

• Cada dispositiu s’identifica en el context de l’estacio amb un nom unic. Per exemple,el port serie /dev/ttyS0 o COM1 pot identificar-se amb un nom que especifiqui la sevafuncio dins el sistema, com ara port del sensor tal.

• Cal que el sistema pugui donar acces a tots els ports serie (i ports USB, que son un casparticular de port serie) i framegrabbers de cada node, que son les interfıcies hardwaremes utilitzades en robotica.

Comunicacio amb Sistemes Externs

• El sistema ha de ser capac d’adaptar la interfıcie dels seus components a les especificacionsde diferents sistemes externs, com per exemple ROS, MOOS, etc.

• El sistema ha de ser capac de comunicar-se amb components mitjancant diferents vies ex-ternes de comunicacio, com per exemple CORBA o Hypertext Transfer Protocol (HTTP).

26

Page 42: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Capıtol 4

Disseny

Havent elaborat una especificacio funcional (3.3) que descriu com ha de ser el sistema, calelaborar un disseny que compleixi aquesta especificacio. Donat que les tecniques d’orientacioa objectes son la millor manera que es coneix de desenvolupar grans i complexes aplicacions isistemes [Cline et al., 1999], aquest disseny sera orientat a objectes i es descriura amb diagramesUML 2.2.

La descripcio del disseny es fa seguint com a guia l’estandard IEEE 1016, sobre descripcionsdel disseny de software [IEEE Computer Society, 2009].

4.1 Arquitectura del Sistema

S’ha plantejat un disseny en cinc moduls: un modul nucli i quatre moduls addicionals queproporcionen al nucli un conjunt de funcions concretes, tal com mostra la figura 4.1.

Figura 4.1: Disseny modular del sistema.

El modul Core representa el nucli del sistema, i s’encarrega de les funcions clau. Els altres

27

Page 43: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

package OverviewData [ ]

IStation

ILogger IAal

CStation

I/O

IComponent

Networking

CComponentFactory CLoggerCComponent CAal

Data Manipulation Threading

˙use¨˙use¨

Figura 4.2: Diagrama de classes amb l’esbos inicial del disseny.

quatre moduls, mes especialitzats, li permeten al nucli fer la resta de funcions:

• Networking : permet a les estacions comunicar-se entre elles, i al sistema amb altressistemes externs a traves de la xarxa.

• Data Manipulation: el format en que les dades s’intercanvien dins el sistema es XML(vegeu l’especificacio funcional, punt 4.2.1). Aixı, doncs, cal poder convertir aquestesdades en format XML a dades de tipus que puguin operar-se aritmeticament o logica:enters, reals, booleans, vectors, matrius... aixı com fer l’operacio inversa. Aquest modulproporciona les eines per fer-ho.

• Threading : proporciona les classes per crear nous fils d’execucio i poder executar tasquessimultaniament.

• I/O : proporciona un acces uniforme i facil als dispositius d’entrada/sortida.

La figura 4.2 mostra aquest esbos inicial del disseny.

4.2 Descripcio Detallada del Disseny

La figura 4.3 mostra totes les classes que componen el model i les relacions entre elles. Totseguit es repassara cada modul, aprofundint els detalls de disseny.

28

Page 44: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

package Data Main[ ]

I/O

CSerialPortAdapterCFrameGrabberAdapter

IIODevice

CFrameGrabber

CIOFactory

CFakeSerialPort

ISerialPort IFrameGrabber

CSerialPort

Networking

CCorbaProxy

Data Manipulation

CConcreteDataStructure

CGenericDataManip

CConcreteDataManip

CGenericDataStructure

Threading

CNonPeriodicThreadCPeriodicThread

CThreadFactory IThread

CComponentFactoryCStation

ILogger IAal

CXmlRpcClient

IStation

CSlaveStation

CComponent

CXmlRpcProxy

CAalCLogger

CMasterStation

CStationFactory

IComponent

CRosProxy

CConcreteComponent

CXmlRpcServer

Main

˙use¨ ˙use¨˙use¨ ˙use¨˙use¨

˙use¨˙use¨˙use¨

˙use¨

˙use¨

˙use¨

˙use¨

˙use¨˙use¨

˙use¨ ˙use¨

Figura 4.3: Diagrama de classes de l’arquitectura dissenyada (vista general).

29

Page 45: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

package CoreData [ ]

+getName() : String+isEnabled() : Boolean+setEnabled( enabled : Boolean ) : void

+initialize() : void

+getConfiguration() : String+setConfiguration( configuration : String ) : void+handleServiceRequest( xmlInput : String, binaryInput : BinaryArray, xmlOutput : String, binaryOutput : BinaryArray ) : void

+update( publisherName : String, topicName : String, xmlData : String, binaryData : BinaryArray ) : void

IComponent

+publish( topicName : String, xmlData : String, binaryData : BinaryArray )#station() : IStation#aal() : IAal#logger() : ILogger#addServiceRequestHandler( serviceName : String, srh : ServiceRequestHandler ) : void#addUpdateHandler( topicName : String, uh : UpdateHandler ) : void-runServiceRequestHandler( serviceName : String ) : void-runUpdateHandler( topicName : String, publisherName : String ) : void

CComponent

+run() : void+getComponent( componentName : String ) : IComponent+getConfiguration() : String+saveConfiguration( componentName : String ) : void+getIODevice( deviceName : String ) : IIODevice

...

IStation

-loadMasterStationSettings() : void-generateStationSettings( stationName : String ) : void

CMasterStation

+createComponent( settings ) : IComponent+registerComponent( componentName : String ) : void+addComponent( component : IComponent ) : void-allocateComponent( componentName : String ) : void

CComponentFactory

+invokeEvent( eventName : String ) : void

IAal

#init() : void#loadSettings( settings : String ) : void-setUpLoggerPatterns() : void-setUpLoggerChannels() : void-setUpIODevices() : void-createComponentsAndProxies() : void-initSubscriptions() : void-initComponents() : void-wait() : void

CStation

+startNewSession( header ) : void+mission( logLine : String ) : void+system( logLine : String ) : void

ILogger

+instance() : Main+getStation() : IStation

Main

+createStation() : IStation

CStationFactory

ConcreteComponent

-waitForCentralStation() : void

CSlaveStation

CAal CLogger

˙use¨˙use¨

˙use¨

˙use¨

˙use¨

Figura 4.4: Diagrama de classes del modul Core.

4.2.1 El Modul Core

El modul Core s’encarrega de les seguents funcions:

• Gestio de components.

• Comunicacio entre components (compartida amb el modul Networking).

• Comunicacio d’esdeveniments.

• Gestio de configuracions.

• Enregistrament de logs.

• Distribucio dels components.

• Centralitzacio de la informacio persistent en un sol node.

La figura 4.4 mostra el diagrama de classes d’aquest modul.

Gestio de Components

La interfıcie IComponent representa un component del sistema robotic (p.e. el driver d’unmotor o un segmentador d’imatges). Les seves operacions son:

30

Page 46: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

• getName: permet obtenir el nom del component.

• isEnabled : permet comprovar si el component es troba habilitat.

• setEnabled : permet habilitar o deshabilitar el component.

• initialize: operacio que es cridada nomes pel sistema i nomes una sola vegada per realitzaraccions d’inicialitzacio. Cada component programat per l’usuari decideix quines accionsexecuta aquesta operacio. Tıpicament el que s’hi fara es demanar la configuracio del propicomponent al sistema portant a terme accions d’acord amb els seus parametres i crear uno mes threads per permetre al component executar tasques asıncronament.

• getConfiguration: permet obtenir la configuracio del component.

• setConfiguration: permet aplicar una configuracio al component.

• handleServiceRequest : permet fer una peticio de servei al component i obtenir-ne el re-sultat.

• update: permet publicar dades que el component rep com a subscriptor.

Per mes detalls sobre les operacions handleServiceRequest i update vegeu mes avall Comunicacioentre Components).

La classe CComponentFactory s’encarrega de la creacio dels components concrets (subclasses deCComponent) a partir dels noms i parametres especificats al fitxer de configuracio de sistema;heus aquı una aplicacio del patro de disseny Factory Method [Gamma et al., 1994]. Aquestscomponents concrets son els que desenvoluparan els usuaris del sistema.

La classe base CComponent, a mes, per conveniencia, dona acces a la funcio d’enregistrament delogs (mitjancant la classe CLog) i a l’AAL, encarregada de la comunicacio d’esdeveniments capa l’exterior (mitjancant la classe CAal), aixı com a l’execucio simultania de tasques (a travesde la classe CThreadFactory del modul Threading, vegeu 4.2.4) i a les operacions d’IStation(vegeu mes avall Distribucio dels Components...).

Comunicacio entre Components

La comunicacio entre components ve descrita per la interfıcie IComponent. Per maximitzarla flexibilitat del sistema (vegeu 3.1.3), els components poden fer servir dos estils diferents decomunicacio: publicacio/subscripcio i orientada a servei.

La comunicacio via publicacio/subscripcio es realitza aplicant el patro arquitectonic Publish-Subscribe [Buschmann et al., 1996]. Es tracta d’un sistema de comunicacio que va nomes enuna direccio: un publicador envia dades cap a un subscriptor. D’entrada, aquest patro nomespermet especificar qui envia i qui rep, no permet discriminar el flux d’informacio segons eltipus de dades. Es com si els lectors de diaris i revistes s’haguessin de subscriure a totes les

31

Page 47: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

publicacions d’una editorial a la vegada, en lloc de poder triar les que mes els agraden. De lamateixa manera, es logic pensar que un component pugui publicar dades de diferents categories,i que els components subscriptors estiguin interessats en nomes algunes d’aquestes categories.Per aixo s’ha incorporat el concepte de topic. Un topic representa una categoria de dades.Els publicadors publiquen diferents topics i cada topic es distingeix per un nom. Aixı, elssubscriptors poden subscriure’s nomes als topics que els interessin de cada publicador. A mes,com que cada topic s’identifica amb un nom, els subscriptors poden saber quin tipus de dadeshan rebut abans de processar-les. Com es veura mes endavant, el modul Data Manipulationpermet distingir les dades per topics. La informacio sobre quin component es subscriu a quinstopics de quin altre component s’especifica al fitxer de configuracio de sistema.

La comunicacio orientada a servei segueix els principis de disseny Service-Oriented Architecture(SOA) [Erl, 2004]. Es una comunicacio bidireccional: un component demana un servei a unaltre, aquest l’executa i en torna el resultat al primer. En aquest cas, el component que demanael servei ja coneix per endavant a quin component ho demana, i tambe com s’estructuren tantla peticio de servei com la resposta que rebra.

L’operacio update s’encarrega de la comunicacio via publicacio/subscripcio. Quan un compo-nent vol publicar dades, fa una crida a la seva operacio publish. El que fa l’operacio publish escridar l’operacio update de tots els components que s’han registrat com a subscriptors del quepublica.

L’operacio update crida el handler ∗ que te associat al valor del parametre topicName (mit-jancant l’operacio runUpdateHandler). Perque aixo sigui possible, el component subscriptorhaura d’haver associat cada nom de topic que es capac de manipular amb un handler que seracridat quan arribin dades d’aquell topic. Aquesta associacio la fa el component subscriptormitjancant l’operacio addUpdateHandler. El diagrama de sequencia de la figura 4.5 il·lustratota aquesta interaccio.

∗Un handler es un fragment de codi, tıpicament una funcio, que es crida quan succeeix un cert esdeveniment.

32

Page 48: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Publish-Subscribe Communication Publish-Subscribe Communicationinteraction [ ]

c1 : ConcreteComponent1 c2 : ConcreteComponent2

update(publisherName="", topicName="", xmlData="", binaryData="")2:

runUpdateHandler(publisherName="", topicName="", xmlData="", binaryData="")3:

addUpdateHandler(serviceName="", handler="")1:

Figura 4.5: Diagrama de sequencia: comunicacio entre dos components via publica-cio/subscripcio.

Similarment, l’operacio handleServiceRequest s’encarrega de la comunicacio orientada a servei.El component que fa la peticio fara una crida a l’operacio handleServiceRequest del componental qual va dirigida, i aquest executara una crida a la seva operacio runServiceRequestHandler perexecutar el handler associat al nom del servei demanat (parametre serviceName). L’associacioentre el nom de servei i el handler l’haura fet previament el component que rep la peticio,cridant addServiceRequestHandler.

Comunicacio d’Esdeveniments

La comunicacio d’esdeveniments es gestionada per l’AAL, que es descrita per la interfıcie IAal.Aquesta interfıcie proporciona senzillament una operacio per notificar que un esdeveniment hapassat: invokeEvent. Aquesta operacio s’encarrega de transmetre l’esdeveniment cap on facifalta, ja sigui cap a un sistema de control de missio present al sistema en forma d’un componentmes o be un sistema de control de missio extern que es comuniqui unicament amb l’AAL. L’AALtambe rep les reaccions del sistema extern, les interpreta i duu a terme les accions oportunes(p.e. habilitar o deshabilitar un component, canviar-li la configuracio... etc.).

L’abstraccio de l’AAL en una interfıcie es resultat d’aplicar el patro Strategy [Gamma et al., 1994].D’aquesta manera es poden fer servir facilment, segons uns parametres de configuracio i entemps d’execucio, diferents maneres de trametre els esdeveniments i de despatxar les reaccionsdel sistema extern (fent servir una o altra classe que implementi la interfıcie IAal). Vegeu lafigura 4.6.

33

Page 49: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

package Data [ Aal ]

+publish( topicName : String, xmlData : String, binaryData : BinaryArray )#station() : IStation#aal() : IAal#logger() : ILogger#addServiceRequestHandler( serviceName : String, srh : ServiceRequestHandler ) : void#addUpdateHandler( topicName : String, uh : UpdateHandler ) : void-runServiceRequestHandler( serviceName : String ) : void-runUpdateHandler( topicName : String, publisherName : String ) : void

CComponent

+invokeEvent( eventName : String ) : void

IAal

CAal

Figura 4.6: Diagrama de classes de l’AAL.

package LogsData [ ]

+publish( topicName : String, xmlData : String, binaryData : BinaryArray )#station() : IStation#aal() : IAal#logger() : ILogger#addServiceRequestHandler( serviceName : String, srh : ServiceRequestHandler ) : void#addUpdateHandler( topicName : String, uh : UpdateHandler ) : void-runServiceRequestHandler( serviceName : String ) : void-runUpdateHandler( topicName : String, publisherName : String ) : void

CComponent

+startNewSession( header ) : void+mission( logLine : String ) : void+system( logLine : String ) : void

ILogger

CLogger

Figura 4.7: Diagrama de classes del logger.

Enregistrament de Logs

L’enregistrament de logs es dut a terme pel logger, descrit amb la interfıcie ILogger. Proporcionaoperacions per desar logs de sistema i de missio (system i mission) i per iniciar noves sessionsde log (startNewSession). Vegeu la figura 4.7.

Distribucio dels Components, Gestio de Configuracions i Centralitzacio de la In-formacio

La classe CStation s’encarrega d’aglutinar tots els components presents en un mateix node dela xarxa (a cada node hi haura una estacio), i de gestionar les configuracions. Per conveniencia,tambe dona acces als dispositius d’entrada/sortida del node on es troba. Des d’una estacio,descrita per la interfıcie IStation, es poden fer les seguents operacions:

34

Page 50: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

• run: posar-la a executar.

• getComponent : obtenir una referencia a un component per poder executar les seves ope-racions.

• getConfiguration: obtenir la configuracio d’un component. Tıpicament la cridara uncomponent que vol obtenir la seva propia configuracio per poder-se inicialitzar.

• saveConfiguration: desar la configuracio d’un component. Tıpicament sera feta servir pelcomponent al qual correspon la configuracio que es vol desar.

• getIODevice: obtenir una referencia a un dispositiu d’entrada/sortida a partir del seunom.

Per poder tenir la informacio centralitzada en una sola estacio, i evitar haver de tenir n fitxersde configuracio replicats a cada node de la xarxa i passar a l’usuari el maldecap d’haver-ne demantenir la coherencia, hi ha dos tipus d’estacions: estacions master (CMasterStation) i esta-cions esclaves (CSlaveStation). En tot moment, nomes hi ha una instancia de CMasterStationen tota la xarxa, que es la que emmagatzema i gestiona el fitxer de configuracio de sistema iel de configuracio de tots els components. A la resta de nodes que intervenen en el sistema hicorren instancies de CSlaveStation, que accedeix a la informacio de configuracio demanant-lia l’estacio central a traves de la xarxa. A les estacions esclaves nomes hi ha d’haver un petitfitxer de configuracio XML, que indica que l’estacio es d’aquest tipus i quin es el hostname del’estacio central, per tal de poder-hi connectar. Vegeu el disseny estructural d’aquests fitxersde configuracio a 4.5.

Aquesta divisio de la feina entre els dos tipus d’estacions s’ha fet aplicant el patro arqui-tectonic Master-Slave [Buschmann et al., 1996], fet efectiu amb patro de disseny Template[Gamma et al., 1994]).

A cada node hi ha d’haver nomes una instancia o be de CMasterStation o be de CSlaveStation.Per garantir-ho s’ha fet servir una combinacio dels patrons Singleton [Gamma et al., 1994] iFactory Method. El patro Singleton no pot aplicar-se directament sobre CStation o alguna de lesseves subclasses, ja que implica amagar-ne el constructor fent-lo privat i es tracta de classes quehan de poder-se instanciar (concretament, CStationFactory ha de poder crear-ne instancies).El que s’ha fet es aplicar el Singleton a la classe principal, Main. Aquesta classe crea sotademanda (versio lazy del patro Singleton) una estacio, fent servir la classe CStationFactory.Per accedir a l’estacio creada es fa servir el metode getStation de la classe Main. Vegeu cominteractuen aquests objectes al diagrama del proces d’inicialitzacio del sistema (figura 4.8).

4.2.2 El Modul Networking

El modul Networking s’encarrega de les seguents funcions:

• Comunicacio entre components (compartida amb el modul Core).

35

Page 51: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

interaction Initialization Initialization[ ]

: CStationFactory

main()

: IStation

: Main

6:

7:

getStation()3:

instance()1:

run()9:

2:

4:

createStation()5:

8:

Figura 4.8: Diagrama de sequencia: proces d’inicialitzacio del sistema. El programa principal,main(), accedeix a la instancia unica de la classe Main fent una crida a instance. A continuaciocrida a getStation, que retornara una instancia o be d’una estacio master o be d’una estacioesclava. Per fer-ho, getStation crea un objecte de tipus CStationFactory, que s’encarrega decrear l’estacio apropiada mitjancant l’operacio createStation. Finalment, el programa principalcrida l’operacio run de l’estacio creada.

36

Page 52: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

• Comunicacio amb sistemes externs.

Vegeu el diagrama de classes d’aquest modul a la figura 4.11.

Comunicacio Entre Components (a Traves de la Xarxa)

Quan els components que volen comunicar-se comparteixen un mateix espai de memoria, lasolucio es trivial: l’emissor te una referencia cap al receptor, i executa una operacio d’aquestultim per a trametre-li les dades i si escau rebre una resposta. Pero, i si els components estroben en nodes diferents de la xarxa? O, i si els components amb els que es vol interactuares troben en un sistema extern? D’acord amb els requeriments del sistema (seccio 3.1), calque la comunicacio a traves de la xarxa sigui transparent per als components: han de poder-secomunicar de la mateixa manera (fent servir la mateixa interfıcie) tant amb un component queresideix a la mateixa maquina com amb un que es a l’altra punta de la xarxa. Es aquı on elpatro Proxy [Gamma et al., 1994] entra en joc.

Els detalls de la comunicacio via xarxa s’encapsulen en una classe proxy, que implementa lainterfıcie IComponent. Aixı, quan un component que es en un node vol comunicar-se amb uncomponent que es en un altre node, aquest no te perque saber-ho: tindra una referencia a unobjecte de tipus IComponent com en qualsevol altre cas de comunicacio. El que passara enrealitat, pero, es que quan el component emissor vulgui cridar una operacio del componentreceptor, estara cridant la operacio de la classe proxy.

Si el component receptor pertany al propi sistema, aquest proxy sera de la classe CXmlO-verTcpProxy, que al seu torn utilitza la classe CXmlOverTcpClient per traduir la crida enuna peticio que s’enviara cap a l’altre component mitjancant el protocol propi del sistema,eXtensible Markup Language over Transmission Control Protocol (XMLoTCP) (vegeu els de-talls d’aquest protocol 4.6). A l’altre extrem, una estacio rebra la peticio mitjancant la classeCXmlOverTcpServer, i la traduira de nou en una crida al component receptor local. Si escau,el servidor respondra a l’emissor amb el resultat de l’operacio.

Si el component receptor pertany a un sistema extern (p.e. ROS), s’utilitzara un proxy dissenyatper a interactuar amb aquest sistema extern.

A mes, fer servir aquesta tecnica proporciona un avantatge molt important: en cas que es vulguifer servir una altre protocol per comunicar els components del sistema (p.e. un protocol basaten UDP, CORBA, ICE...), o que es vulgui interactuar amb un nou sistema extern, el que calfer es nomes afegir un altre proxy (una sola classe).

D’aquesta manera, en una estacio no nomes hi ha instancies dels components que s’hi executen,sino que tambe hi ha una instancia d’una classe proxy per cada component que es troba enuna estacio remota o en un sistema extern. D’aquesta manera tots el components del sistemapoden accedir a qualsevol altre component (indiferentment de si es troba a la mateixa estacio,en una altra o en un sistema extern). Vegeu l’exemple de la figura 4.10.

37

Page 53: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

De la creacio de components reals i dels proxies se n’encarrega la classe CComponentFactorydurant la inicialitzacio, segons el que especifiqui el fitxer de configuracio de sistema. Al diagramade sequencia de la figura 4.9 es mostra aquest proces amb un exemple. Aquest exemple constadels seguents passos:

• Passos 1-3: el programa principal, que ha creat una estacio (objecte de tipus CStation)seguint el procediment mostrat a la figura 4.8, posa a executar aquesta estacio cridant-nel’operacio run. Aquesta, al seu torn, crida init i setUpIODevices per inicialitzar-se.

• Passos 4-9: l’estacio crea els components seguents: dos components reals, de tipus Con-creteComponent1 i ConcreteComponent2 ; un proxy per comunicar-se amb un componentd’una altra estacio via XMLoTCP (de tipus CXmlOverTcpProxy), que al seu torn crea unobjecte de tipus CXmlOverTcpClient per efectuar les comunicacions (pas 7); un proxy (detipus CRosProxy) per comunicar-se amb un component que es troba en un sistema ROS;altres components, simbolitzats amb la lınia de vida titulada amb uns punts suspensius(...).

• Pas 10: l’estacio carrega la informacio sobre subscripcions a partir del fitxer de configu-racio de sistema (vegeu 4.5).

• Passos 11 a 20: l’estacio crida l’operacio initialize de tots els components que ha creat,un a un.

• Passos 21 a 25: l’estacio executa la seva operacio wait fins a la fi de l’execucio del sistema.Paral·lelament, passa el seguent:

– El component de tipus ConcreteComponent1 executa la seva operacio run, duent aterme algun tipus de processament (pas 24).

– L’objecte de tipus ConcreteComponent2 senzillament espera que altres objectes s’hicomuniquin via peticio de servei o via publicacio/subscripcio (vegeu 4.2.1).

– El proxy XMLoTCP va remetent les crides a les seves operacions cap al seu desti-natari final (pas 22).

– El proxy ROS tambe va despatxant les crides a les seves operacions.

– Opcionalment, els altres components creats podran tambe executar tasques en pa-ral·lel (pas 21).

• Finalment, quan tots els components han finaitzat la seva execucio o be l’estacio rep certevent via l’AAL, el sistema acaba la seva execucio (pas 26).

Comunicacio amb Sistemes Externs

La comunicacio amb sistemes externs, que poden fer servir protocols de comunicacio diferentsal d’aquest sistema i que tenen components que no implementen la mateixa interfıcie es resolconstruint un proxy per a cada interfıcie externa.

38

Page 54: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Component Creationinteraction Initialization[ ]

: ConcreteComponent1

: ConcreteComponent2

: CXmlOverTcpServer

: CXmlOverTcpProxy

main()

: CRosProxy

: CStation

: ...

[Parallel execution]

par

12:

run()23:

14:

25:

16:

7:

run()22:

run()1:

18:

init()2:

setUpIODevices()3:

initSubscriptions()10:

4:

5:

6:

8:

9:

initialize()11:

initialize()13:

initialize()15:

initialize()17:

initialize()19:

wait()24:

26:

20:

run()21:

Figura 4.9: Diagrama de sequencia: exemple de creacio de diferents components i proxies.

39

Page 55: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Component A!

Estació 1!

Component B!

Proxy de D!

Proxy dʼE!

Proxy de C!

Estació 2!

Proxy de D!

Proxy dʼE!

Component C!

Proxy de B!

Proxy de B!

MOOS!

Component D!

ROS!

Component E!

XMLoTCP!

MOOS!

ROS!

Figura 4.10: Exemple de comunicacio entre components mitjancant proxies. L’estacio 1 albergaels components A i B i un proxy per a comunicar-se amb C (que es a l’estacio 2). L’estacio2 alberga el component C, i dos proxies per a A i B (que son a l’estacio 1). A mes, hi ha elscomponents D (ubicat en un sistema MOOS) i E (ubicat en un sistema ROS); les estacions 1 i2 creen proxies per a comunicar-s’hi.

40

Page 56: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Networkingpackage Data [ ]

+getName() : String+isEnabled() : Boolean+setEnabled( enabled : Boolean ) : void

+initialize() : void

+getConfiguration() : String+setConfiguration( configuration : String ) : void+handleServiceRequest( xmlInput : String, binaryInput : BinaryArray, xmlOutput : String, binaryOutput : BinaryArray ) : void

+update( publisherName : String, topicName : String, xmlData : String, binaryData : BinaryArray ) : void

IComponent

Networking

+handleRequest( data ) : void

IXmlRpcHandler

+sendRequest( data ) : void

CXmlOverTcpClient

CCorbaProxy

+run() : void

CXmlOverTcpServer CRosProxy

CXmlOverTcpProxy

+createComponent( settings ) : IComponent+registerComponent( componentName : String ) : void+addComponent( component : IComponent ) : void-allocateComponent( componentName : String ) : void

CComponentFactory

#init() : void#loadSettings( settings : String ) : void-setUpLoggerPatterns() : void-setUpLoggerChannels() : void-setUpIODevices() : void-createComponentsAndProxies() : void-initSubscriptions() : void-initComponents() : void-wait() : void

CStation

˙use¨

˙use¨ ˙use¨ ˙use¨

˙use¨

Figura 4.11: Diagrama de classes del modul Networking.

A mes del proxy propi per comunicar components intersistema, se n’han dissenyat dos mes. Elprimer (CCorbaProxy) permet comunicar amb objectes CORBA. La solucio software utilitzadaal CIRS abans d’aquest projecte (vegeu 1.1) estava elaborada amb aquesta eina. Per aixo esva construir aquest proxy, que es capac d’interactuar amb l’arquitectura anterior.

El segon (CRosProxy) permet comunicar amb la plataforma per a sistemes robotics ROS[ROS.org, 2010]. ROS sera utilitzat en el robot GIRONA 500, actualment en desenvolupa-ment, en el marc d’un projecte de recerca europeu en el qual diverses universitats desenvolupenmoduls per a aquest vehicle. Tots els partners del projecte s’han posat d’acord per fer servirROS per a intercomunicar aquests moduls.

De fet, en aquests dos casos s’esta aplicant la idea del patro Adapter [Gamma et al., 1994], jaque el que s’ha fet es adaptar la interfıcie externa a IComponent.

41

Page 57: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

4.2.3 El Modul Data Manipulation

Aquest modul s’encarrega d’una tasca aparentment senzilla, pero clau en un sistema on totesles comunicacions es basen en XML. El que fa es convertir estructures de dades (i.e. tuples) adocuments XML i viceversa. Vegeu-ne el diagrama de classes a la figura 4.12.

Totes les classes d’aquest modul operen basant-se en documents XML que tenen una estructuradeterminada, descrita a 4.4.

La classe CXmlDataManip es l’encarregada de parsejar i carregar a memoria els documentsXML i de comprovar que tenen l’estructura correcta. Les seves operacions permeten fer re-ferencia als elements dels documents XML mitjancant la sintaxi arrel/fill/fill del fill..., a l’estild’XPath [W3C, 1999].

La classe CGenericDataManip fa servir CXmlDataManip per convertir el text XML en valorsde tipus enter, real, cadena de caracters, boolea, vector, matriu o vector de paraules o per ferl’operacio inversa.

Un cop definida la tupla que es vol convertir, cal crear una subclasse de CGenericDataManipper poder-la traduir a XML. Cada subclasse representa un topic: una categoria de dades. Perexemple, pot haver-hi el topic Navegacio o el topic Estat del Sistema. Les dades contingudesen un topic son una tupla amb elements que poden ser dels tipus que CXmlDataManip potgestionar. Tots els topics s’identifiquen amb un nom.

Les conversions des de i cap a XML seran quelcom molt comu en tots els components delsistema, i per tant s’ha dissenyat la classe CGenericDataManip pensant que aquesta tasca siguiel mes senzilla possible de fer. Les seves operacions son les seguents:

• getName: obtenir el nom del topic amb els que s’esta operant.

• loadXmlString : carregar a memoria un document XML que segueix l’estructura descritaa 4.4.

• data: proporciona acces de lectura i d’escriptura a la tupla, per poder-ne modificar elscamps.

• getXmlString : obtenir la representacio actual de la tupla en XML.

• stringifyNames : retorna una cadena de caracters amb els noms de cada camp de la tuplaseparats per espais. Es util per generar les capcaleres dels fitxers de log.

• stringifyValues : retorna una cadena de caracters amb els valors de cada camp de la tuplaseparats per espais. Es util per generar les files dels fitxers de log.

Vegeu a 4.4 els detalls de l’estructura dels documents XML i exemples de conversio.

42

Page 58: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Data Manipulationpackage Data [ ]

Data Manipulation

+loadXmlFile( filePath : String ) : void+loadXmlString( xmlString : String ) : void+createEmptyDocument( name : String ) : void+itemExists( xmlPath : String ) : Boolean+getXmlString() : String+getSection() : String+getSiblingSections() : Sequence+getInteger( xmlPath : String ) : Integer+getReal( xmlPath : String ) : double+getString( xmlPath : String ) : String+getBoolean( xmlPath : String ) : Boolean+getVector( xmlPath : String ) : Vector+getMatrix( xmlPath : String ) : Matrix+getWordArray( xmlPath : String ) : WordArray+addInteger( xmlPath : String, tagName : String, value : Integer ) : void+addReal( xmlPath : String, tagName : String, value : double ) : void+addString( xmlPath : String, tagName : String, value : String ) : void+addBoolean( xmlPath : String, tagName : String, value : boolean ) : void+addVector( xmlPath : String, tagName : String, value : Vector ) : void+addMatrix( xmlPath : String, tagName : String, value : Matrix ) : void+addWordArray( xmlPath : String, tagName : String, value : WordArray ) : void+saveToFile() : void

CXmlDataManip

CConcreteDataStructureCConcreteDataManip

: CXmlDataManip : CXmlDataManip

+loadXmlString( xmlString : String ) : void+getXmlString() : String+data() : GenericDataStructure+getName() : String+stringifyNames() : String+stringifyValues() : String

CGenericDataManip

Figura 4.12: Diagrama de classes del modul Data Manipulation.

4.2.4 El Modul Threading

El modul Threading s’encarrega de l’execucio simultania de tasques. Vegeu-ne el diagrama declasses a la figura 4.13. Hi ha una classe per representar els fils d’execucio periodics (CPe-riodicThread) i una per els no periodics (CNonPeriodicThread). Ambdues implementen lainterfıcie IThread, d’aquesta manera resulta facil afegir un altre tipus de fil d’execucio en casque calgui. En efecte, es tracta d’una altra aplicacio del patro Strategy. La creacio dels threadses confina a la classe CThreadFactory (patro Factory Method).

4.2.5 El Modul I/O

El modul I/O s’encarrega de l’acces a dispositius d’entrada/sortida. Vegeu-ne el diagrama declasses a la figura 4.14. Suporta acces a ports serie (tambe a ports USB, interfıcies que podentractar-se de la mateixa manera que els ports serie) i framegrabbers. Es facil, pero, afegir-hinous dispositius abstraient-los amb la interfıcie IIODevice (patro Strategy).

IIODevice descriu qualsevol dispositiu d’entrada/sortida com un data stream, amb les seguentsoperacions:

• read : llegeix el nombre de bytes especificat des de l’stream. L’operacio fara timeout si no

43

Page 59: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Threadingpackage Data [ ]

Threading

+createThread( mode : EMode, period : Integer ) : void

CThreadFactory

+start( functor : Functor ) : void

IThread

CNonPeriodicThreadCPeriodicThread

˙use¨˙use¨

Figura 4.13: Diagrama de classes del modul Threading.

s’han rebut dades durant el nombre especificat de milisegons (msTimeout). Si msTimeoutes 0, llavors l’operacio s’esperara fins que s’hagin rebut tots tants bytes com numOfBytes.Si numOfBytes es 0, llavors l’operacio seguira llegint dades fins que no n’hi hagi mes dedisponibles a l’stream. En tots els casos, totes les dades llegides s’emmagatzemaran adataBuffer.

• readByte: llegir un sol byte des de l’stream. L’operacio fara timeout si no s’han rebutdades durant el nombre especificat de milisegons (msTimeout). Si msTimeout es 0, llavorsl’operacio s’esperara fins que hi hagi dades disponibles a l’stream.

• readLine: llegir una cadena de caracters des de l’stream.

• readUntil : llegir des de l’stream fins que es troba el byte especificat. Les dades llegidess’emmagatzemaran a dataBuffer, incloent-hi el byte delimitador.

Les interfıcies ISerialPort i IFrameGrabber descriuen les operacions que es poden fer, respec-tivament, amb un port serie (p.e. configurar el baud rate o el nombre de bits de parada) iamb una framegrabber (p.e. configurar la resolucio). D’aquesta manera es facil crear afegirnous tipus de dispositius (altre vegada, patro Strategy) o fins i tot dispositius que representinun port serie o una framegrabber falsa. Aixo ultim es molt util en la fase de proves, ja quepermet testejar components sense haver de disposar del dispositiu fısic, senzillament reproduintun fitxer de text o un vıdeo.

La classe CIOFactory s’encarrega de crear l’objecte d’entrada/sortida apropiat segons unsparametres de configuracio (patro Factory Method).

44

Page 60: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

package Data [ I/O ]

I/O

+readByte( msTimeout : Integer ) : byte+read( dataBuffer : DataBuffer, nBytes : Integer, msTimeout : Integer ) : void+readLine( msTimeout : Integer, lineTerminator : char ) : String+write( data : DataBuffer ) : void+readUntil( dataBuffer : DataBuffer, delimiter : Integer, msTimeout : Integer ) : void

IIODevice

CSerialPortAdapterCFrameGrabberAdapter

+createDevice() : IIODevice

CIOFactory CFrameGrabber

CFakeSerialPort

ISerialPort IFrameGrabber

CSerialPort

˙use¨ ˙use¨

˙use¨

˙use¨˙use¨

Figura 4.14: Diagrama de classes del modul I/O.

4.2.6 Tot Junt

A la figura 4.15 es mostra el diagrama de classes complet del disseny, mostrant les relacionsentre tots els moduls que s’han explicat.

4.3 Discussio de Dissenys Alternatius

A continuacio es plantegen dues idees de disseny que finalment han estat descartades.

4.3.1 Separacio dels conceptes publicador i subscriptor

Inicialment es va pensar en separar aquests conceptes creant una interfıcie per als objectessubscriptors, ISubscribe i una subclasse de CComponent per als publicadors, CPublisher. Elsobjectes subscriptors reimplementarien l’operacio update d’ISubscribe per tractar les dades comfos necessari i CPublisher proporcionaria a les seves subclasses una implementacio de l’operaciopublish. El fet que els conceptes s’identifiquin amb una interfıcie i una classe fa possible queuna subclasse pugui ser publicadora i subscriptora a la vegada, sense haver de forcar herenciamultiple. Vegeu la figura 4.16.

45

Page 61: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

package Data [ All ]

I/O

+readByte( msTimeout : Integer ) : byte+read( dataBuffer : DataBuffer, nBytes : Integer, msTimeout : Integer ) : void+readLine( msTimeout : Integer, lineTerminator : char ) : String+write( data : DataBuffer ) : void+readUntil( dataBuffer : DataBuffer, delimiter : Integer, msTimeout : Integer ) : void

IIODevice

CSerialPortAdapterCFrameGrabberAdapter

+createDevice() : IIODevice

CIOFactory CFrameGrabber

CFakeSerialPort

ISerialPort IFrameGrabber

CSerialPort

Data Manipulation

+loadXmlFile( filePath : String ) : void+loadXmlString( xmlString : String ) : void+createEmptyDocument( name : String ) : void+itemExists( xmlPath : String ) : Boolean+getXmlString() : String+getSection() : String+getSiblingSections() : Sequence+getInteger( xmlPath : String ) : Integer+getReal( xmlPath : String ) : double+getString( xmlPath : String ) : String+getBoolean( xmlPath : String ) : Boolean+getVector( xmlPath : String ) : Vector+getMatrix( xmlPath : String ) : Matrix+getWordArray( xmlPath : String ) : WordArray+addInteger( xmlPath : String, tagName : String, value : Integer ) : void+addReal( xmlPath : String, tagName : String, value : double ) : void+addString( xmlPath : String, tagName : String, value : String ) : void+addBoolean( xmlPath : String, tagName : String, value : boolean ) : void+addVector( xmlPath : String, tagName : String, value : Vector ) : void+addMatrix( xmlPath : String, tagName : String, value : Matrix ) : void+addWordArray( xmlPath : String, tagName : String, value : WordArray ) : void+saveToFile() : void

CXmlDataManip

+loadDataXmlString( xmlString : String ) : void+loadConfigXmlString( xmlString : String ) : void+getDataXmlString() : String+getConfigXmlString() : String+data() : GenericDataStructure+config() : GenericDataStructure+getDataName() : String+getConfigName() : String+stringifyDataNames() : String+stringifyConfigNames() : String+stringifyDataValues() : String+stringifyConfigValues() : String

CComponentDataManip

CConcreteDataStructureCConcreteDataManip

+getName() : String+isEnabled() : Boolean+setEnabled( enabled : Boolean ) : void

+initialize() : void

+getConfiguration() : String+setConfiguration( configuration : String ) : void+handleServiceRequest( xmlInput : String, binaryInput : BinaryArray, xmlOutput : String, binaryOutput : BinaryArray ) : void

+update( publisherName : String, topicName : String, xmlData : String, binaryData : BinaryArray ) : void

IComponent

Networking

+handleRequest( data ) : void

IXmlRpcHandler

+sendRequest( data ) : void

CXmlOverTcpClient

CCorbaProxy

+run() : void

CXmlOverTcpServer CRosProxy

CXmlOverTcpProxy

+publish( topicName : String, xmlData : String, binaryData : BinaryArray )#station() : IStation#aal() : IAal#logger() : ILogger#addServiceRequestHandler( serviceName : String, srh : ServiceRequestHandler ) : void#addUpdateHandler( topicName : String, uh : UpdateHandler ) : void-runServiceRequestHandler( serviceName : String ) : void-runUpdateHandler( topicName : String, publisherName : String ) : void

CComponent

Threading

+createThread( mode : EMode, period : Integer ) : void

CThreadFactory

+start( functor : Functor ) : void

IThread

CNonPeriodicThreadCPeriodicThread

-loadMasterStationSettings() : void-generateStationSettings( stationName : String ) : void

CMasterStation

+run() : void+getComponent( componentName : String ) : IComponent+getConfiguration() : String+saveConfiguration( componentName : String ) : void+getIODevice( deviceName : String ) : IIODevice+addComponent( c : IComponent ) : void

IStation

+createComponent( settings ) : IComponent+registerComponent( componentName : String ) : void+addComponent( component : IComponent ) : void-allocateComponent( componentName : String ) : void

CComponentFactory

+invokeEvent( eventName : String ) : void

IAal

#init() : void#loadSettings( settings : String ) : void-setUpLoggerPatterns() : void-setUpLoggerChannels() : void-setUpIODevices() : void-createComponentsAndProxies() : void-initSubscriptions() : void-initComponents() : void-wait() : void

CStation

+startNewSession( header ) : void+mission( logLine : String ) : void+system( logLine : String ) : void

ILogger

+instance() : Main+getStation() : IStation

Main

+createStation() : IStation

CStationFactory

ConcreteComponent

-waitForCentralStation() : void

CSlaveStation

CLoggerCAal

˙use¨ ˙use¨

˙use¨

˙use¨˙use¨

˙use¨

˙use¨

˙use¨

˙use¨ ˙use¨

˙use¨

˙use¨˙use¨

˙use¨

˙use¨

˙use¨

Figura 4.15: Diagrama de classes de l’arquitectura dissenyada (vista detallada).

46

Page 62: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Alternative1package Data [ ]

+getName() : String+isEnabled() : Boolean+setEnabled( enabled : Boolean ) : void

+initialize() : void

+getConfiguration() : String+setConfiguration( configuration : String ) : void+handleServiceRequest( xmlInput : String, binaryInput : BinaryArray, xmlOutput : String, binaryOutput : BinaryArray ) : void

+update( publisherName : String, topicName : String, xmlData : String, binaryData : BinaryArray ) : void

IComponent

+update( publisherName : String, topicName : String, xmlData : String, binaryData : BinaryArray ) : void

ISubscriber

+publish( topicName : String, xmlData : String, binaryData : BinaryArray )

CPublisher

+publish( topicName : String, xmlData : String, binaryData : BinaryArray )#station() : IStation#aal() : IAal#logger() : ILogger#addServiceRequestHandler( serviceName : String, srh : ServiceRequestHandler ) : void#addUpdateHandler( topicName : String, uh : UpdateHandler ) : void-runServiceRequestHandler( serviceName : String ) : void-runUpdateHandler( topicName : String, publisherName : String ) : void

CComponent

ConcreteComponent

Figura 4.16: Diagrama de classes de la separacio dels conceptes publicador i subscriptor (alter-nativa de disseny descartada).

Finalment es va decidir integrar aquestes funcionalitats a la classe CComponent. D’aquestamanera la implementacio d’un component resulta mes senzilla, ja que no cal especificar si uncomponent es subscriptor o publicador, senzillament ho es per defecte.

4.3.2 Distincio entre DataManips generics i especıfics

Inicialment es va pensar en crear dos tipus de manipuladors de dades: els generics, que efec-tivament han estat presents al disseny (classe CGenericDataManip), i els especıfics. Aquestsdarrers estaven pensats per treballar amb dues estructures de dades a la vegada: una de da-des generiques i una de configuracio. Aixı, cada component del sistema tindria associat unmanipulador, que li permetria gestionar un tipus de dades i la seva configuracio. Tıpicament,el component faria servir l’estructura de dades generica per emmagatzemar la informacio quepubliques, i la de configuracio per gestionar la seva configuracio en particular. La figura 4.17mostra el diagrama de classes d’aquesta possible solucio.

Finalment, pero, es va decidir que aquesta opcio de disseny afegia complexitat al sistemainnecessariament, i per tant es va descartar.

4.4 Disseny de l’estructura dels documents XML

Com s’ha dit, tot l’intercanvi de dades del sistema es basa en documents XML. Tots aquestsdocuments representen topics, que s’identifiquen per un nom. Les dades contingudes en untopic son tuples del nombre d’elements que es vulgui, on tots els seus elements tenen un nomidentificador i poden ser dels seguents tipus:

47

Page 63: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

CXmlOverTcpProxy Alternative2class [ ]

Data Manipulation

+loadXmlFile( filePath : String ) : void+loadXmlString( xmlString : String ) : void+createEmptyDocument( name : String ) : void+itemExists( xmlPath : String ) : Boolean+getXmlString() : String+getSection() : String+getSiblingSections() : Sequence+getInteger( xmlPath : String ) : Integer+getReal( xmlPath : String ) : double+getString( xmlPath : String ) : String+getBoolean( xmlPath : String ) : Boolean+getVector( xmlPath : String ) : Vector+getMatrix( xmlPath : String ) : Matrix+getWordArray( xmlPath : String ) : WordArray+addInteger( xmlPath : String, tagName : String, value : Integer ) : void+addReal( xmlPath : String, tagName : String, value : double ) : void+addString( xmlPath : String, tagName : String, value : String ) : void+addBoolean( xmlPath : String, tagName : String, value : boolean ) : void+addVector( xmlPath : String, tagName : String, value : Vector ) : void+addMatrix( xmlPath : String, tagName : String, value : Matrix ) : void+addWordArray( xmlPath : String, tagName : String, value : WordArray ) : void+saveToFile() : void

CXmlDataManip

+loadDataXmlString( xmlString : String ) : void+loadConfigXmlString( xmlString : String ) : void+getDataXmlString() : String+getConfigXmlString() : String+data() : GenericDataStructure+config() : GenericDataStructure+getDataName() : String+getConfigName() : String+stringifyDataNames() : String+stringifyConfigNames() : String+stringifyDataValues() : String+stringifyConfigValues() : String

CComponentDataManip

: CXmlDataManip : CXmlDataManip

+loadXmlString( xmlString : String ) : void+getXmlString() : String+data() : GenericDataStructure+getName() : String+stringifyNames() : String+stringifyValues() : String

CGenericDataManip

CConcreteComponentDataManip

CConcreteDataManip CConcreteDataStructure CComponentConfigStructureCComponentDataStructure

Figura 4.17: Diagrama de classes de la distincio manipuladors generics i especıfics (alternativade disseny descartada).

• Enter

• Real

• Cadena de caracters

• Boolea

• Vector

• Matriu

• Vector de paraules

Per exemple, podrıem tenir el topic estat del robot, que podem representar de la seguent maneraen pseudocodi:

1 topic estat_del_robot

2 passos_fets: enter. Valor = 1324.

3 temperatura: real. Valor = 33.5.

4 nom: cadena. Valor = "manel".

5 actiu: boolea . Valor = cert.

6 posicio: vector. Valor = 2, 10, 18.

7 transformacio: matriu. Valor = 0,0,1; 1,0,0; 0,-1,0;

8 que_veus: vector de paraules. Valor = "paret", "terra ".

9 ftopic

La conversio a XML es fa seguint aquests passos:

48

Page 64: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

• El node arrel del document s’anomena igual que el topic.

• Per cada element de la tupla, s’afegeix un node fill a l’arrel.

• Cada element fill s’anomena igual que el seu corresponent camp de l’estructura. Unatribut anomenat type indica el seu tipus, i un atribut anomenat value indica el seu valor.

Aixı, el topic estat del robot quedaria de la manera seguent:

1 <estat_del_robot >

2 <passos_fets type="integer" value="1324" />

3 <temperatura type="real" value="33.5" />

4 <nom type="string" value="manel" />

5 <actiu type="boolean" value="true" />

6 <posicio type="vector" value="2, 10, 18" />

7 <transformacio type="matrix" value="0,0,1; 1,0,0; 0,-1,0;" />

8 <que_veus type="word_array" value="paret terra" />

9 </estat_del_robot >

Notes:

• Com pot veure’s, els valors possibles de l’atribut type son integer, real, string, boolean,vector, matrix i word array, corresponents als tipus possibles escrits en angles.

• En l’atribut value d’un vector, els seus elements poden separar-se fent servir espais icomes.

• En l’atribut value d’una matriu, els elements de les seves files poden separar-se fent servirespais i comes. Per separar files es fan servir punts i coma.

• Els elements d’un vector de paraules poden separar-se fent servir espais i comes. Cadaparaula nomes pot contenir caracters alfanumerics i underscores.

4.5 Disseny de l’Estructura dels Fitxers de Configuracio

4.5.1 Fitxer de sistema

El fitxer de sistema te dues estructures possibles depenent de si es troba en una estacio mastero en una estacio slave. Es distingeixen per l’atribut role del node arrel, que pot tenir els valorsmaster o slave. En tots els casos el node arrel s’anomena sempre station cfg.

49

Page 65: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Fitxer de sistema per a l’estacio master

El fitxer de l’estacio master es el que especifica totes les configuracions de totes les estacions.Les estacions slave es connectaran a l’estacio master per demanar-li la seva configuracio. Elfitxer consta de tres seccions: logger, stations i subscriptions.

A la seccio logger hi ha la configuracio referent a l’enregistrament de logs. Conte cinc parametres:

• single line comment chars : indica amb quins caracters comenca cada lınia de comentari(les de la capcalera, vegeu 3.3.2).

• system pattern: el patro de les lınies dels logs de sistema. Aquest patro permet ferapareixer informacio com la data i l’hora en que s’ha guardat la lınia. Vegeu-ne l’especi-ficacio a [POCO C++ Libraries, 2010].

• mission pattern: el patro de les lınies dels logs de missio. Segueix el mateix format queels logs de sistema.

• enable console logger : determina si es mostren els logs per consola o no. Pot ser true ofalse.

• enable file logger : determina si es desen els logs a fitxer o no. Pot ser true o false.

La seccio stations descriu quines estacions intervenen en el sistema. Per cada estacio (que teassociat un nom), descriu:

• La informacio d’entrada/sortida (seccio io):

– Port on escolta el servidor XMLoTCP (element xmlotcp port). En cas que es ne-cessiti, en aquesta seccio tambe s’hi indicara qualsevol informacio requerida per unsistema de comunicacio extern.

– Dispositius d’entrada/sortida que ofereix l’estacio (elements device de la subsecciodevices). A tots els elements hi ha un atribut type que indica el tipus de dispositiu(serial port o framegrabber) i un atribut name que indica el nom del dispositiu. Perals port serie cal, a mes, especificar el valor dels atributs path, baud rate, char size,stop bits, parity i flow control per poder configurar-los. Per a les framegrabberss’especifiquen els atributs path, width, height i depth.

• Quins components aglutina l’estacio (seccio components). Cada element component dinsaquesta seccio designa un component que intervindra en el sistema indicant del seu nom(atribut name), si inicialment esta habilitat o no (atribut enabled) i per quina via decomunicacio es pot accedir al component. Si es fa servir el protocol XMLoTCP propi delsistema el seu valor sera xmlotcp, i si es fa servir un sistema de comunicacio extern alsistema, com ROS o CORBA el seu valor sera ros o corba.

50

Page 66: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Finalment, la seccio subscriptions indica quins components estan subscrits a quins altres i aquins topics. Per cada subscripcio hi ha un element subscription, amb una tripleta d’atributs:

• publisher : nom del component publicador.

• subscriber : nom del component subscriptor.

• topic: nom d’un dels topics que publica el publicador.

Els noms poden fer referencia a qualsevol component definit a la seccio components de qualsevolestacio.

A continuacio es mostra un exempre de configuracio d’estacio master on :

• Els logs es mostren a la consola i es desen en fitxers.

• Hi ha dues estacions amb un component a cada una. Tots els components es comuniquenvia XMLoTCP.

• El component d’una estacio esta subscrit al de l’altra.

1 <station_cfg role="master">

2

3 <logger >

4 <single_line_comment_chars >% </single_line_comment_chars >

5 <system_pattern >%Y-%m-%d %H:%M:%S.%i:%p: %t</system_pattern >

6 <mission_pattern >%Y %m %d %H %M %S %i %t</

information_pattern >

7 <enable_console_logger >true</enable_console_logger >

8 <enable_file_logger >true</enable_file_logger >

9 </logger >

10

11

12 <stations >

13

14 <station name="aquesta_estacio">

15 <io>

16 <xmlotcp_port >12000</xmlotcp_port >

17 <devices >

18 <device type="serial_port" name="

port_dels_motors" path="/dev/ttyACM0"

baud_rate="19200" char_size="8" stop_bits="

1" parity="NONE" flow_control="NONE" />

19 <device type="framegrabber" name="camera" path

="/dev/video0" width="640" height="480"

depth="8" />

51

Page 67: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

20 </devices >

21 </io>

22

23 <components >

24 <component name="productor_de_dades" enabled="true"

via="xmlotcp" />

25 </components >

26 </station >

27

28 <station name="estacio_esclava">

29 <io>

30 <xmlotcp_port >12000</xmlotcp_port >

31 <devices/>

32 </io>

33

34 <components >

35 <component name="consumidor_de_dades" enabled="true"

via="xmlotcp" />

36 </components >

37 </station >

38

39 </stations >

40

41

42 <subscriptions >

43 <subscription publisher="productor_de_dades" subscriber="

consumidor_de_dades" topic="dades" />

44 </subscriptions >

45

46 </station_cfg >

Fitxer de sistema per a una estacio slave

El fitxer de configuracio per a una estacio slave senzillament indica que es tracta d’una estacioslave, quin es el hostname i el port XMLoTCP de l’estacio master per poder-hi connectar iquin es el nom d’aquesta estacio. Per exemple:

1 <station_cfg role="slave" name="estacio_esclava">

2 <master_hostname >192.168.1.2 </master_hostname >

3 <master_port >12000</master_port >

4 </station_cfg >

52

Page 68: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

4.5.2 Fitxer de components

El fitxer de configuracio de components esta format per un node arrel que s’anomena config,del qual pengen tants topics com es vulgui. Per associar un topic amb un component, cal queel topic s’anomeni el nom del component seguit de configuration. Vegem un exemple on hi hauna configuracio tıpica de dos components:

1 <config >

2 <component_a_configuration >

3

4 <timeout_port_serie type="real" value="5000" />

5 <nom_dispositu_a_usar type="string" value="port_serie_tal" />

6 <calcular_x type="boolean" value="true" />

7

8 </component_a_configuration >

9

10 <component_b_configuration >

11

12 <offset type="real" value="1.6" />

13 <nom_dispositiu_camera type="string" value="camera0" />

14

15 </component_b_configuration >

16 </config >

4.6 Disseny del Protocol de Comunicacio XMLoTCP

4.6.1 Bases del Protocol

Connexio i intercanvi de dades

El protocol fa servir una connexio TCP persistent al port especificat per una estacio. Tots elsmissatges que s’intercanvien son en format XML. Totes les peticions i respostes es succeeixensıncronament.

Format del Contenidor dels Missatges

Un missatge consisteix en un element XML contenidor i una comanda tambe en format XMLa dins. Totes les comandes enviades i rebudes s’han d’encapsular de la seguent manera:

1 <msg len="123" cksum="234">

2 ...

53

Page 69: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

3 </msg>

On:

• len: la longitud de la comanda (el text interior de msg).

• cksum: el checksum de la comanda.

Format de les Comandes

Les comandes indiquen al servidor que ha d’executar una operacio. Tenen la seguent forma:

1 <nom_comanda >

2 ...

3 </nom_comanda >

On nom comanda es el nom de la comanda.

Format de les Respostes

Un cop s’ha completat l’execucio d’una comanda s’enviara una resposta d’aquesta forma:

1 <response cmd="nom_comanda" type="tipus_resposta">

2 ...

3 </response >

On:

• nom comanda es el nom de la comanda que ha originat la resposta.

• tipus resposta es ok si l’execucio ha tingut exit o error si hi ha hagut algun error.

El text intern de l’element response de la resposta depen de la comanda que s’ha executat. Encas d’error, el text intern sera un missatge d’error.

4.6.2 Comportament dinamic

Inicialitzacio

El seguent es el que passa en una sessio tıpica utilitzant aquest protocol. Una estacio esclava(client) s’ha connectat al servidor de l’estacio master. Un cop li envia la comanda hello, l’estacio

54

Page 70: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

master coneix el hostname del client. L’estacio master s’esperara aleshores que diguin hellototes les altres estacions esclaves que te especificades al fitxer de configuracio de sistema, per talde coneixer-ne tambe el hostname. A continuacio respondra ok a totes les estacions. Aquestes,tıpicament li demanaran la seva configuracio amb la comanda get station config i els hi seraenviada. Vegeu-ho a la figura 4.18. A partir d’aquest moment ja pot comencar l’execucio decomandes entre estacions.

Esclava 1Master ...Esclava 2 Esclava N

<hello/>

<hello/>

<hello/>

<response ... type="ok"/>

<response ... type="ok"/>

<response ... type="ok"/>

<get_station_config ... />

<station_config ... />

Figura 4.18: Diagrama de comunicacio entre estacions esclaves (clients) i estacio master (ser-vidor) durant la inicialitzacio.

Generacio de la configuracio de les estacions esclaves

La resposta de l’estacio master a la comanda get station config es construeix de la seguentmanera:

• Les seccions logger i subscriptions queden igual que al fitxer de configuracio de l’estaciomaster.

• La seccio io de l’estacio que demana la configuracio s’afegeix tal com ve pero com a filladirecta del node arrel.

• No hi ha seccions station. En lloc d’aixo, hi ha una unica seccio components on es llistentots els components de totes les estacions. Als components que s’executen a l’estacio quedemana la configuracio se’ls afegeix un atribut via amb el valor local. Als components

55

Page 71: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

que s’executen en una estacio diferent a la que demana la configuracio aquest atribut te elvalor xmlotcp si utilitza aquest protocol o be ros o corba si fan servir aquestes altres vies.A mes, tambe s’hi afegeixen atributs que indiquen parametres necessaris per establir lesconnexions. Per a cada component no local, l’estacio que fa la peticio creara un objecteproxy (vegeu mes amunt 4.2).

Execucio de comandes

Un cop les estacions han rebut la seva configuracio, els seus proxies ja poden enviar les co-mandes que necessitin per executar les operacions els seus components. En aquest moment lacomunicacio passa a ser peer to peer, ja que totes les estacions actuen de servidor i de client almateix temps. Vegeu-ho a la figura 4.19.

Esclava 1Master ...Esclava 2 Esclava N

<update ... />

<response ... type="ok"/>

<update ... />

<handle_service_request ... />

<response ... type="ok"/>

<response ... type="ok"/>

Figura 4.19: Diagrama de comunicacio entre estacions un cop feta la inicialitzacio. Comunicaciopeer to peer.

Noti’s que un peer pot atendre diverses peticions a la vegada, i enviar altres peticions (com aclient) tambe al mateix temps.

4.6.3 Sessio d’Exemple

Les seguents transaccions representen una sessio estandard un cop s’ha establert la connexio.Noti’s que els checksums no son acurats en aquests exemples.

El client envia:

56

Page 72: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

1 <msg len="10" cksum="123">

2 <hello/>

3 </msg>

El servidor respon amb:

1 <msg len="48" cksum="123">

2 <response cmd="hello" type="ok">

3 </response >

4 </msg>

El client envia:

1 <msg len="54" cksum="123">

2 <get_station_config station_name="estacio_esclava"/>

3 </msg>

Si tot ha anat be, el servidor contesta:

1 <msg len="1177" cksum="123">

2 <response cmd="hello" type="ok">

3 <station_cfg >

4

5 <logger >

6 <single_line_comment_chars >% </single_line_comment_chars >

7 <system_pattern >%Y-%m-%d %H:%M:%S.%i:%p: %t</system_pattern >

8 <mission_pattern >%Y %m %d %H %M %S %i %t</

information_pattern >

9 <enable_console_logger >true</enable_console_logger >

10 <enable_file_logger >true</enable_file_logger >

11 </logger >

12

13

14 <io>

15 <xmlotcp_port >12000</xmlotcp_port >

16 <devices >

17 <device type="serial_port" name="port_dels_motors"

path="/dev/ttyACM0" baud_rate="19200" char_size="8"

stop_bits="1" parity="NONE" flow_control="NONE" />

18 <device type="framegrabber" name="camera" path="/dev/

video0" width="640" height="480" depth="8" />

19 </devices >

20 </io>

21

22 <components >

57

Page 73: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

23 <component name="productor_de_dades" enabled="true" via="local

" />

24 <component name="consumidor_de_dades" enabled="true" via="

xmlotcp" hostname="192.168.1.10" xmlotcp_port="12000" />

25 </components >

26

27

28 <subscriptions >

29 <subscription publisher="productor_de_dades" subscriber="

consumidor_de_dades" topic="dades" />

30 </subscriptions >

31

32 </station_cfg >

33 </response >

34 </msg>

4.6.4 Comandes

Les comandes d’aquest protocol permeten fer les mateixes operacions que l’interfıcie ICompo-nent del disseny.

hello

Inicia la comunicacio. Serveix per indicar al servidor que la sessio ha comencat.

El client envia:

1 <msg len="10" cksum="123">

2 <hello/>

3 </msg>

El servidor respon amb:

1 <msg len="48" cksum="123">

2 <response cmd="hello" type="ok">

3 </response >

4 </msg>

send next

Demana l’enviament del seguent parametre binari d’una comanda o d’una resposta.

58

Page 74: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

El client envia:

1 <msg len="14" cksum="123">

2 <send_next/>

3 </msg>

El servidor respon enviant el seguent parametre binari, consistent en un vector de bytes.

get station config

Obte la configuracio per a una estacio donat el seu nom.

El client envia:

1 <msg len="42" cksum="123">

2 <get_station_config name="nom_estacio"/>

3 </msg>

On nom estacio es el nom de l’estacio de la qual es vol obtenir la configuracio.

Si tot ha anat be, el respon amb:

1 <msg len="42" cksum="123">

2 <response cmd="get_station_name" type="ok">

3 ...

4 </response >

5 </msg>

El text interior de l’element response tindra la forma descrita mes amunt a l’apartat 4.6.2.

get component config

Obte la configuracio d’un component donat el seu nom.

El client envia:

1 <msg len="46" cksum="123">

2 <get_component_config name="nom_component"/>

3 </msg>

On nom component es el nom del component de la qual es vol obtenir la configuracio.

Si tot ha anat be, el respon amb:

59

Page 75: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

1 <msg len="42" cksum="123">

2 <response cmd="get_component_config" type="ok">

3 ...

4 </response >

5 </msg>

El text interior de l’element response sera el topic corresponent a la configuracio del componentdemanada (vegeu 4.5.2).

save component config

Desa la configuracio d’un component donat el seu nom.

El client envia:

1 <msg len="46" cksum="123">

2 <save_component_config name="nom_component">

3 config

4 </save_component_config >

5 </msg>

On nom component es el nom del component de la qual es vol obtenir la configuracio, i configes el topic de la configuracio que vol guardar-se.

Si tot ha anat be, el respon amb:

1 <msg len="64" cksum="123">

2 <response cmd="save_component_config" type="ok">

3 </response >

4 </msg>

El text interior de l’element response sera el topic corresponent a la configuracio del componentdemanada (vegeu 4.5.2).

enable component

Habilita un component donat el seu nom.

El client envia:

1 <msg len="46" cksum="123">

2 <enable_component name="nom_component"/>

60

Page 76: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

3 </msg>

On nom component es el nom del component que es vol habilitar.

Si tot ha anat be, el servidor respon amb:

1 <msg len="59" cksum="123">

2 <response cmd="enable_component" type="ok">

3 </response >

4 </msg>

El text interior de l’element response tindra sera el topic corresponent a la configuracio delcomponent demanada (vegeu 4.5.2).

disable component

Funciona igual que enable component, pero fa l’operacio inversa.

update

Publica dades cap a un component.

El client envia:

1 <msg len="46" cksum="123">

2 <update to="nom_subscriptor" from="nom_publicador" topic="nom_topic"

binary_param_lengths="1024 2048 4096">

3 ...

4 </update >

5 </msg>

On:

• nom subscriptor es el nom del component que rep les dades.

• nom publicador es el nom del component publicador.

• nom topic es el nom del topic que es publica.

• binary param lengths son les mides (enters positius) de cada parametre binari d’entradaque tingui la crida a l’operacio update.

61

Page 77: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

El text interior de l’element update correspon al topic que es publica.

Mentre no hagi rebut tots els parametres en forma de vector de bytes, el servidor va responent:

1 <msg len="14" cksum="123">

2 <send_next/>

3 </msg>

I el client li va enviant els parametres. Quan ha rebut tots els parametres i ha executat l’operacioamb exit, el servidor respon:

1 <msg len="49" cksum="123">

2 <response cmd="update" type="ok">

3 </response >

4 </msg>

handle service request

Executa una peticio de servei a un component.

El client envia:

1 <msg len="42" cksum="123">

2 <handle_service_request to="nom_component" service_name="nom_servei"

binary_param_lengths="1024 2048 4096">

3 ...

4 </handle_service_request >

5 </msg>

On:

• nom component es el nom del component al qual es demana el servei.

• nom servei es el nom del servei que es demana.

• binary param lengths son les mides (enters positius) de cada parametre binari d’entrada.

El text interior de l’element handle service request es variable depenent del servei que es demani.

Mentre no hagi rebut tots els parametres en forma de vector de bytes, el servidor va responent:

1 <msg len="14" cksum="123">

2 <send_next/>

3 </msg>

62

Page 78: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

I el client li va enviant els parametres. Quan ha rebut tots els parametres i ha executat l’operacioamb exit, el servidor respon:

1 <msg len="42" cksum="123">

2 <response cmd="handle_service_request" type="ok"

binary_param_lengths="1024 2048 4096">

3 ...

4 </response >

5 </msg>

El text interior de l’element response correspon al parametre XML de sortida. Els elements debinary param lengths contenen les mides dels parametres binaris de sortida. Mentre no hagirebut tots els parametres en forma de vector de bytes, el client va enviant:

1 <msg len="14" cksum="123">

2 <send_next/>

3 </msg>

I el servidor envia la resta de parametres.

63

Page 79: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

64

Page 80: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Capıtol 5

Implementacio

Implementar el disseny d’un sistema de software complex com el que ens ocupa no es, a diad’avui, una tasca trivial. Durant aquesta fase sorgeixen encara moltes situacions on cal prendreuna decisio. En aquest capıtol s’explica la guia d’estil que s’ha seguit per obtenir un codi mesfacil de mantenir (seccio 5.1), el proces de documentacio del codi (seccio 5.2), les bibliotequesde programacio que s’han fet servir (seccions 5.3 i 5.4) i finalment els detalls d’implementacioque ha calgut resoldre (5.5).

5.1 Guia d’Estil

Quan es treballa en un projecte de milers de lınies de codi, cal adoptar unes convencions al’hora de programar: com s’escriuen els noms de les variables, com es distingeixen les variablesque son atribut d’una classe, en quin ordre van els parametres de les funcions, on cal posarespais en blanc a les expressions... coses d’aquest estil, que no son forcades pel compilador.D’aquesta manera, quan algu esta revisant un tall de codi que no ha escrit li es molt mes facilllegir-lo i entendre’l. Aixı es facilita la deteccio d’errors i el manteniment.

Hi ha diversa literatura sobre bones practiques de codificacio [McConnell, 2004], i d’especıficasobre C++ [Sutter and Alexandrescu, 2005]. S’ha realitzat recerca sobre convencions de codifi-cacio ja estipulades que poguessin fer-se servir en el desenvolupament d’aquest projecte. Moltescompanyies de software tenen les seves propies convencions, com Google [Google, Inc., 2010]o id Software [id Software, Inc., 2010], per citar-ne dues de capdavanteres que treballen ambC++. Despres de considerar diverses alternatives, que tenien en comu el fet de ser o be mas-sa generiques o be massa orientades a un projecte en particular, vaig trobar la guia d’estilutilitzada per l’empresa Geotechnical Software Services [Geotechnical Software Services, 2008].Aquesta guia te en compte les convencions mes acceptades per la comunitat internacional dedesenvolupadors en C++, aixı com les propostes de la literatura mes comunament utilitzada.La codificacio de la solucio s’ha fet seguint aquesta guia d’estil.

65

Page 81: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

5.2 Documentacio

Per documentar les interfıcies, classes, funcions, etc. s’ha seguit la sintaxi de Doxygen [van Heesch, 2009].Doxygen es un sistema de documentacio que suporta el llenguatge C++ i que permet generardocumentacio extensiva de tot un projecte en diversos formats (entre ells HTML, LATEX, RTF,PostScript, PDF hiperenllacat i man pages de UNIX). Per fer-ho, cal afegir comentaris C++abans de la declaracio de l’ıtem que es vol documentar (sempre als fitxers de capcalera, els .h)seguint un format concret.

L’IDE que s’ha fet servir, Eclipse CDT, proporciona un plug-in per poder generar la documen-tacio amb Doxygen fent nomes un clic.

5.3 Biblioteques de Programacio de Tercers

En enginyeria del software, cal evitar sempre reinventar la roda (a no ser que volguem aprendremes coses sobre la roda en si) [Atwood, 2009]. Per aixo es molt important fer servir bones bi-blioteques de programacio que proporcionin funcions tıpiques, que ja s’han implementat moltesvegades en el passat. En aquest projecte, a mes de l’Standard Template Library (STL), s’hanfet servir les seguents biblioteques de programacio.

5.3.1 Boost C++ Libraries

Es tracta d’una molt util col·leccio de biblioteques de proposit general, que ofereix un muntd’eines. De totes elles, en aquest projecte s’han fet servir:

• Boost.Array, contenidors estil STL de mida constant.

• Boost.Asio, entrada/sortida asıncrona, incloent xarxa, sockets, timers, resolucio de host-names i acces a ports serie.

• Boost.Bind, per gestio de callbacks.

• Boost.Date Time, per operacions relacionades amb dates i hores.

• Boost.Foreach, que afegeix a C++ una construccio linguıstica per iterar facilment sobretots els elements d’una sequencia.

• Boost.Function, objectes funcio (punters a funcions encapsulats).

• Boost.Lambda, per definicio de petits objectes funcio sense nom just al lloc de la crida, al’estil de la programacio funcional.

• Boost.Lexical Cast, conversions de text literal, com per exemple un enter representantuna cadena de caracters, o viceversa.

66

Page 82: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

• Boost.Multi-Array, per matrius n-dimensionals.

• Boost.Optional, per a parametres i valors de retorn opcionals.

• Boost.Random, per generar nombres aleatoris.

• Boost.Regex, pel maneig d’expressions regulars.

• Boost.Smart Ptr, per gestio automatica de memoria dinamica.

• Boost.Thread, multi-threading portable en C++.

• Boost.Tokenizer, per trencar una cadena de caracters en series de tokens.

• Boost.Utility, per crear objectes no copiables i thread-safe lazy singletons (vegeu mes avall5.5.11).

5.3.2 POCO C++ Libraries

Com les Boost, les biblioteques POCO son de proposit general, pero orientades a componentsque fan tasques de relatiu alt nivell (POCO ve de Portable Components). Se n’han fet servirels seguents paquets:

• XML, per enregistrament de logs.

• Logging, per enregistrament de logs.

• Filesystem, per gestio del sistema de fitxers.

5.3.3 OpenCV

OpenCV es una biblioteca que permet capturar imatges amb framegrabbers, a mes de processar-les amb molts algorismes i operacions de visio per computador com per exemple segmentacions,transformades de Hough, dilate, erode, open o close. S’han fet servir per implementar l’acces aframegrabbers del modul I/O. Els components desenvolupats sobre el sistema que fan proces-sament d’imatges fan servir tambe aquestes biblioteques.

5.3.4 Eigen

Es una biblioteca per a fer operacions algebraiques en C++: vectors, matrius i algorismesrelacionats. Tots els calculs amb matrius i vectors numerics del sistema s’han implementatamb Eigen. L’eleccio d’Eigen per a l’algebra es va fer despres de provar les eines algebraiquesmicro Basic Linear Algebra Subprograms (uBLAS) incloses a les biblioteques Boost i veure quetant la seva sintaxi complicada com les operacions que oferia no eren les mes adequades persatisfer als requeriments del sistema.

67

Page 83: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

5.3.5 LibSerial

Inicialment es va fer servir la biblioteca LibSerial, que permet accedir a ports serie en sistemesPOSIX. Pero aqueta biblioteca no pot funcionar en entorns multi-threading intensius, com esel cas, i per aixo va deixar-se de banda en favor de Boost.Asio. Vegeu-ne els detalls a 6.2.2.

5.4 Biblioteques del Sistema

Durant la implementacio han sorgit necessitats de programacio que es repeteixen a molts puntsdel sistema, i que no estan resoltes o no estan resoltes prou satisfactoriament per una bibliotecade tercers. Per aixo s’ha implementat una biblioteca per satisfer aquestes necessitats per al propisistema i tambe per a oferir als usuaris la possibilitat de fer servir les solucions implementades.

La biblioteca desenvolupada consta dels seguents moduls:

• Numeric: derivades, integrals, transformacions algebraiques 2D i 3D, conversio d’unitatsi definicio de constants.

• EKF : implementacio d’un Extended Kalman Filter, un metode matematic molt utilitzaten robotica, sobretot per tasques de navegacio, mapping i SLAM.

• PID : implementacio d’un controlador PID (controlador proporcional-integral-derivatiu),ampliament utilitzat en sistemes de control.

5.5 Detalls d’Implementacio

Tot seguit es repassen els problemes mes rellevants que han sorgit durant la fase d’implementacioi s’explica com s’han resolt.

5.5.1 Particularitats del C++

Interfıcies

La distincio entre classes i interfıcies es una potent caracterıstica present a llenguatges comJava o C#, pero no al C++. Com es pot definir una interfıcie en C++? Basicament, enC++ una interfıcie es una classe que te totes les seves member functions no estatiques (i.e.els metodes d’instancia) declarades com a pure virtual (excepte el destructor) i cap membreprivat. A [Llamas, 2005] es presenta una solucio que incorpora al llenguatge els tokens interfacei implements fent servir macros de preprocessador. Donat que les macros son perjudicials per

68

Page 84: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

moltes raons [Cline et al., 1999] i que s’hi fa servir sintaxi no estandard, es tracta d’una soluciopoc portable.

Per aixo es va decidir declarar les interfıcies com classes amb nomes pure virtual member functi-ons, i distingint-les comencant el seu nom amb la lletra I, d’interfıcie. Vegem la implementaciod’una interfıcie d’exemple, que te nomes una operacio anomenada f que no rep ni retorna capparametre:

1 /*

2 * IExemple.h

3 *

4 * Interfıcie d’exemple

5 */

6

7 #ifndef IEXEMPLE_H_

8 #define IEXEMPLE_H_

9

10 class IExemple {

11 public:

12 virtual void f() = 0 ;

13

14 virtual ~IExemple () {}

15 } ;

16

17 #endif /* IEXEMPLE_H_ */

Per evitar memory leaks, es important declarar el destructor de la interfıcie com a virtual idefinir-lo. El perque esta detalladament explicat a [Cline et al., 1999].

Llistes d’inicialitzacio

Si un programador ha treballat amb Java o C#, segurament estara acostumat a escriure elconstructor d’una classe de manera que inicialitzi els seus atributs assignant-los valors. Aixı,en C++ podria definir el constructor per defecte d’una classe A que te dos atributs x i y detipus int d’aquesta manera:

1 //

2 // Mal constructor en C++

3 //

4 A::A()

5 {

6 x = 42;

7 y = 1;

8 }

69

Page 85: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Per raons d’eficiencia, C++ te una construccio especıfica per inicialitzar els atributs d’una clas-se en el constructor, anomenada initialization list ; a mes, als atributs de tipus non-static consti non-static reference es impossible assignar-los valors dins el cos del constructor [Cline, 2010].Per aixo es sempre recomanable fer servir una initialization list. Aixı, l’exemple anterior que-daria:

1 //

2 // Constructor amb "initialization list"

3 //

4 A::A():

5 x(42),

6 y(1)

7 {

8 }

Objectes no copiables

Per defecte, els compiladors de C++ defineixen sempre un constructor copia i un operadord’assignacio per a totes les classes, encara que el programador no els hagi declarat. Aixo potser un maldecap en moltes situacions, sobretot si els atributs de la classe manipulen dispositiusd’entrada/sortida o recursos de xarxa.

Per evitar aixo, es poden declarar el constructor copia i l’operador d’assignacio a la part privadai no definir-los. Pero aixo implica recordar i fer aquesta repetitiva tasca per a totes les classesde les quals es vol evitar la copia, que poden ser moltes.

Fent servir herencia privada i la classe noncopyable de Boost.Utility, pero, es pot declarar unaclasse com a no copiable elegantment en una sola lınia:

1 /*

2 * CNoCopiable.h

3 *

4 * Classe no copiable

5 */

6

7 #ifndef CNOCOPIABLE_H_

8 #define CNOCOPIABLE_H_

9

10 #include <boost/noncopyable.hpp >

11

12 class CNoCopiable : private boost :: noncopyable {

13 // ...

14 } ;

15

16 #endif /* CNOCOPIABLE_H_ */

70

Page 86: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Tot el que cal escriure per aconseguir una classe no copiable es a la lınia 12. El que succeeix esbasicament que la classe noncopyable te el constructor copia i l’operador d’assignacio declaratscom a privats, i en heredar-ne privadament provoquen que CNoCopiable tambe els hi tingui.Aquesta tecnica te a mes l’avantatge que fa no copiables tambe totes les subclasses de la classeon s’ha aplicat. Per exemple, la classe base CComponent del sistema dissenyat (vegeu capıtol4) s’ha fet no copiable, i per tant tots els components que es desenvolupin seran tambe nocopiables.

Excepcions

S’han fet servir les excepcions estandard de l’STL per gestionar situacions d’error o imprevistes.Aixı, quan succeeix quelcom inesperat en el codi es llanca una excepcio, i quan es criden funcionsque poden generar excepcions s’empra una estructura try-catch per gestionar-les.

5.5.2 Modul Data Manipulation

CGenericDataManip fa us de CXmlDataManip per convertir topics de documents XML a tuples(structs, en C++) i viceversa. A les subclasses creades a partir de CGenericDataManip se lesha anomenat data manipulators.

La implementacio d’aquesta classe s’ha realitzat prioritzant la facilitat de crear nous datamanipulators. Inicialment, es va pensar en fer servir sols herencia, i deixar que l’usuari reim-plementes les funcions loadXmlString i getXmlString. Aixı, per crear un data manipulator pera una estructura com la seguent:

1 struct TopicExemple {

2 int i;

3 double d;

4 bool b;

5 //...

6 }

Caldria crear una subclasse de CGenericDataManip (anomenada, per exemple CTopicExem-pleDataManip) que redefinıs les esmentades funcions, aixı:

1 void CTopicExempleDataManip :: loadXmlString( const std:: string&

xmlDocument )

2 {

3 try {

4 xmlDataManip.loadXmlString( xmlDocument );

5 topic.i = xmlDataManip.getInteger( "topic_exemple/i" )

;

6 topic.d = xmlDataManip.getReal( "topic_exemple/d" );

71

Page 87: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

7 topic.b = xmlDataManip.getBoolean( "topic_exemple/b" )

;

8 //...

9 }

10 catch ( std:: exception& e ) {

11 // Gestionar com calgui l’excepcio ...

12 }

13 }

14

15 std:: string CTopicExempleDataManip :: getXmlString ()

16 {

17 try {

18 xmlDataManip.createEmptyDocument( "topic_exemple" );

19 xmlDataManip.addInteger( "topic_exemple", "i", topic.i

);

20 xmlDataManip.addReal( "topic_exemple", "d", topic.d );

21 xmlDataManip.addBoolean( "topic_exemple", "b", topic.b

);

22 //...

23 }

24 catch ( std:: exception& e ) {

25 // Gestionar com calgui l’excepcio ...

26 }

27 }

Nota: xmlDataManip es un private data member de tipus CXmlDataManip, i topic n’es un detipus TopicExemple.

Com pot observar-se, hi ha molt codi repetitiu, propens a escriure’s fent servir la tecnicadel copy & paste i per tant amb molta probabilitat que hi apareixin errors per descuits delprogramador. A mes, en aquest exemple, encara faltaria redefinir les funcions stringifyNamesi stringifyValues, amb codi igualment tedios. I caldria crear dos fitxers, el .h de la declaracio iel .cpp de la implementacio.

Fent servir tecniques de programacio generica i els poc coneguts pero utils pointers to mem-bers que ofereix el llenguatge C++, s’ha pogut fer una implementacio de CGenericDataManipque permet crear subclasses on nomes cal definir el seu constructor. Aixı, l’exemple anteriorquedaria reduıt al seguent:

1 class CTopicExempleDataManip : public CGenericDataManip < TopicExemple

> {

2 public:

3 CTopicExempleDataManip ():

4 CGenericDataManip < TopicExemple >( "echosounder_data"

) // Definicio del nom del topic

5 {

6 addItem( "i", &TopicExemple ::i ) ;

72

Page 88: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

7 addItem( "d", &TopicExemple ::d ) ;

8 addItem( "b", &TopicExemple ::b ) ;

9 //...

10 }

11 } ;

Pot observar-se que tot el data manipulator es pot descriure en un sol fitxer .h, o be directamental mateix fitxer del programa on es vulgui fer servir. Noti’s tambe que no cal cridar unafuncio diferent per a cada tipus d’element, sino que addItem s’encarrega de fer tota la feina.Un cop definit el constructor de la subclasse, la classe base CGenericDataManip proporcionaimplementacions per defecte de totes les seves funcions. D’aquesta manera s’assoleix l’objectiude simplificar al maxim les operacions amb documents XML.

Tot seguit es dona una ullada als detalls mes importants de la implementacio que s’ha fet dela classe CGenericDataManip. El codi font complet de la classe pot trobar-se a l’apendix A.

La classe CGenericDataManip te un data member (i.e. atribut) de tipus parametritzable D ala seccio protected. Per conveniencia, es declara un typedef anomenat DataType per a D.

1 template < typename D >

2 class CDataManip {

3 public:

4 typedef D DataType ;

5 //...

6

7 protected:

8 DataType data_ ;

9 //...

10 } ;

D s’instancia com el tipus de l’struct que es vol manipular.

La seccio private de la classe alberga contenidors associatius (i.e. maps de l’STL) on les clausson noms d’ıtems del topic que es manipula, i les dades associades son un punter a un membrede l’struct que representa el topic. Hi ha un contenidor per a cada tipus possible d’ıtem (enter,real, boolea... etc.). La funcio generica addItem permet afegir parelles de nom i punter alcontenidor adequat. A partir d’aquesta funcio generica, s’ha creat una funcio sobrecarregada,tambe anomenada addItem, per a cada tipus de dades possible en un topic. Aquestes funcionssobrecarregades permeten instanciar la funcio generica amb el tipus adequat. Vegeu el codicomplet de la implementacio a l’apendix A.

73

Page 89: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

5.5.3 CComponentFactory amb Programacio Generica

La classe CComponentFactory s’encarrega de crear el component (una subclasse de CCom-ponent) adequat un cop se li ha passat el seu nom com a argument. Aquest procediment,pero, presenta implica que el tipus concret del component que cal crear s’ha de coneixer entemps de compilacio. Aixı, una primera idea per implementar la funcio createComponent deCComponentFactory podria ser la seguent:

1 IComponent* CComponentFactory :: createComponent( const std:: string&

name )

2 {

3 if ( name == "nom1" )

4 return new Component1;

5 else if ( name == "nom2" )

6 return new Component2;

7 // ...

8 }

Obviament, aquesta no es una bona solucio, ja que implica canviar el codi d’aquesta funciocada vegada que s’afegeix un nou component al sistema. El que s’ha fet es crear una funciogenerica, anomenada registerComponent, que permet associar el nom del component amb el seutipus (de fet, amb un punter a una funcio que executa el constructor del component). Aquestafuncio guarda l’associacio en un contenidor associatiu (i.e. un map de l’STL) i, quan es cridaa createComponent, aquesta el que fa es cercar el nom del component dins el contenidor perexecutar la funcio corresponent.

D’aquesta manera, abans de fer servir el component nomes cal escriure la seguent lınia en algunpunt del programa:

1 CComponentFactory :: registerComponent < ClasseComponent >( "

nom_component" ) ;

Aleshores, ja es pot fer servir el nom del component al fitxer de configuracio de sistema (vegeul’apartat 4.5.1), i el component es creara automaticament durant la inicialitzacio (vegeu figura4.8).

5.5.4 Comunicacio via TCP/IP

Boost.Asio (ASIO ve d’Asynchronous Input/Output) ofereix la possibilitat, de fer servir conne-xions TCP. Tota la biblioteca presenta una interfıcie uniforme, permet fer servir un socket comsi es tractes d’un IO Stream de l’STL. Permet tambe dur a terme comunicacions asıncrones mit-jancant callbacks. Fins al moment, pero, nomes ha calgut implementar comunicacions sıncrones.

74

Page 90: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Totes les comunicacions via xarxa del sistema, incloent el servidor i el client XMLoTCP i totsels proxies del modul Networking s’han implementat fent servir Boost.Asio.

La caracterıstica mes important que ofereix Boost.Asio des del punt de vista del sistema desen-volupat es la capacitat de crear facilment servidors multithread que permeten atendre diversesconnexions simultaniament de manera senzilla.

5.5.5 Acces a Ports Serie

Boost.Asio ofereix una classe anomenada serial port, que permet llegir i escriure dades a travesd’un port serie. Per implementar l’acces a ports serie, s’ha adaptat la interfıce d’aquesta classea la d’ISerialPort (vegeu capıtol 4), aplicant el patro Adapter via composicio, tal com mostrael diagrama de classes de la figura 5.1.

SerialPortImplementationpackage Data [ ]

boost::asio::serial_portCSerialPort

ISerialPort

Figura 5.1: Diagrama de classes de l’acces a ports serie adaptant la classe serial port de labiblioteca Boost.Asio.

5.5.6 Multiplexador de Ports Serie (Opcio Finalment Descartada)

En un moment del desenvolupament, va sorgir la necessitat de compartir l’acces a un port serieentre dos components. Va resultar que una mateixa placa electronica controlava els motors i ala vegada tenia un conjunt de sensors per monitoritzar temperatures, pressions i voltatges. Laplaca es feia anar enviant comandes a traves del port serie, a els quals la placa responia despresde fer l’accio demanada.

Per solucionar aixo, la primera idea va ser crear dos components: un que controles els motors iun que llegıs els sensors. Aquests components compartirien un mateix port serie. Podrien enviarel que volguessin a la vegada (el port estaria protegit per una exclusio mutua), i nomes rebrienels missatges de la placa que encaixessin amb un conjunt d’expressions regulars determinats.

La implementacio es va fer amb exit, pero va resultar excessivament complicada de fer servir,ja que calia tenir en compte massa detalls. Finalment, es va decidir crear un tercer component

75

Page 91: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

que representes la placa en sı. Llavors, mitjancant peticions de servei, els altres dos componentsenviaven les comandes que calia a la placa i en rebien la resposta evitant la complexitat de lesexpressions regulars i les condicions de carrera.

5.5.7 Enregistrament de Logs

L’enregistrament de logs s’ha solucionat amb les biblioteques POCO, que proporcionen unexcel·lent framework per a aquesta tasca que es thread-safe i gestiona automaticament lesescriptures a disc. A mes, permet especificar quina informacio apareix al principi de cada lıniadel log (p.e. data, hora o hostname de la maquina) segons un patro configurable, satisfentdirectament aquest requeriment (vegeu 3.1). De fet, les classes que resolen l’enregistrament delogs funcionen basicament com a adaptadors del logging framework de les biblioteques POCO(patro Adapter).

El framework d’enregistrament de logs de les POCO ofereix a mes la caracterıstica de classificarels missatges en diferents categories que especifiquen la seva funcio. Aquestes categories son:fatal, critical, error, warning, notice, information, debug i trace. Com que aquesta es unacaracterıstica molt util, s’ha decidit donar-li presencia en el disseny. Per fer-ho s’han agrupatles diverses categories de logs de sistema en una interfıcie, ISystemLogger. Aleshores, el metodesystem de la interfıcie ILogger dona acces a un objecte de tipus ISystemLogger. El diagramade classes del logger ha quedat com es mostra a la figura 5.2.

LoggerImplpackage Data [ ]

+startNewSession( header ) : void+mission( logLine : String ) : void+system() : ISystemLogger

ILogger

+fatal( logLine : String )+critical( logLine : String )+error( logLine : String )+warning( logLine : String )+notice( logLine : String )+information( logLine : String )+debug( logLine : String )+trace( logLine : String )

CSystemLogger

+fatal( logLine : String )+critical( logLine : String )+error( logLine : String )+warning( logLine : String )+notice( logLine : String )+information( logLine : String )+debug( logLine : String )+trace( logLine : String )

ISystemLogger

CLogger

Figura 5.2: Diagrama de classes definitiu del logger del sistema implementat amb el paquetLogging de les biblioteques POCO.

Aixı, des d’un component es pot desar un missatge de log de tipus, per exemple, debug de lamanera seguent:

1 logger ().system ().debug("Missatge");

76

Page 92: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

5.5.8 Maneig de Memoria amb Smart Pointers

En C++, l’us de memoria dinamica requereix, d’entrada, una gestio especıfica per part delprogramador. Per exemple, quan creem un nou objecte amb l’operador new :

1 Objecte* obj = new Objecte;

Cal que ens cuidem de destruir-lo quan ja no se’l necessita mes:

1 delete obj;

Per evitar haver de fer tota aquesta tediosa gestio, en llenguatges com C++ es construeixenel que s’anomenen smart pointers, que son punters que s’encarreguen automagicament de ferla recollida d’escombraries. La biblioteca Boost.Smart Ptr ofereix∗ fins a sis smart pointersde caracterıstiques diferents per fer servir en situacions especıfiques, dels quals s’han utilitataquests dos:

• scoped ptr : destrueix l’objecte que apunta quan surt d’ambit o quan se li fa apuntar a unaltre objecte (se’l reinicia). Es util per fer-lo servir amb data members que requereixenpolimorfisme, entre d’altres. No permet, pero, copiar-lo i per tant compartir-lo entre varisobjectes.

• shared ptr : destrueix l’objecte que apunta quan es destrueix o reinicia l’ultim shared ptrque apunta aquest objecte. Permet, a diferencia de scoped ptr, compartir-lo entre diferentsobjectes i fer-lo servir en contenidors.

Fent servir aquests punters intel·ligents evitem que el programador s’hagi de fer carrec de lagestio de memoria, simplificant els programes i fent-los menys propensos a errors.

5.5.9 Gestio de Callbacks amb Boost.Function i Boost.Bind

En informatica, un callback es una referencia a un tros codi executable que es passa com aargument a un altre codi. El disseny d’aquest sistema fa us intensiu d’aquest recurs en diferentspunts: la classe CComponent, per exemple, permet especificar callbacks† (tambe anomenatshandlers) per a peticions de servei i actualitzacions; i els objectes de tipus IThread es posena executar un cop se’ls ha passat un callback com a argument. Tambe la implementacio del’acces a xarxa amb Boost.Asio requereix la utilitzacio de callbacks.

∗L’STL ofereix un smart pointer anomenat auto ptr, pero te una complicada semantica de copia que impedeix,entre altres, fer-lo servir en contenidors [Sutter, 2009] i que complicava innecessariament els programes.†Un callback es una porcio de codi, tıpicament una funcio, que pot passar-se com a argument a altres porcions

de codi perque el puguin executar.

77

Page 93: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Boost.Function i Boost.Bind son una potent eina per treballar amb callbacks. Boost.Functionpermet encapsular punters a funcions, evitant d’aquesta manera la complicada sintaxi d’a-questes entitats i podent treballar-hi facilment com amb qualsevol altre objecte: copiant-los,passant-los com a parametre, etc.

Boost.Bind permet convertir qualsevol crida a una funcio en C++, ja sigui a una static function,member function o free function en un objecte de Boost.Function. D’aquesta manera, es potindicar facilment a un thread que executi una member function d’un component, per exemple.

5.5.10 Threads

Els threads no periodics s’han implementat com un adapter de la classe deadline timer deBoost.Asio (ni Boost ni POCO suporten directament el concepte de thread periodic). La classedeadline timer permet iniciar un temporitzador que compta fins que un determinat temps hapassat, i a continuacio executa un callback. Basicament el que s’ha fet es crear un objectede tipus deadline timer que executa el codi del thread cada cop que s’acaba el temps, per acontinuacio reiniciar el comptador i tornar a iniciar el proces.

Els threads periodics s’han implementat com un adapter de la classe thread de Boost.Thread.Per iniciar

Exclusions Mutues i Bloquejos

En ocasions ha calgut fer us d’aquests mecanismes de sincronitzacio de threads. Per exemple, hiha components que poden presentar alguna condicio de carrera si els arriba una actualitzacio ouna peticio de servei executada simultaniament per mes d’un thread. En aquest cas cal utilitzaruna bloqueig en una exclusio mutua per evitar que diversos threads executin l’operacio a lavegada

Boost.Thread ofereix una classe mutex, que representa una exclusio mutua, i diversos objectesbloquejadors amb diferents propietats (dels quals nomes s’ha utilitzat lock guard, que fa lamateixa funcio que un bloqueig convencional). Aquests objectes bloquejadors, pero, tenen laparticularitat que desfan el bloqueig un cop surten d’ambit. Aixı, ja no cal desfer el bloqueigexplıcitament. Per exemple, quan fent us directament de crides al sistema tindrıem el seguentcodi:

1 mutex m;

2

3 if ( i == 0 ) {

4 lock( m ) ;

5 // Seccio crıtica

6 unlock( m ) ;

7 }

78

Page 94: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Fent servir les eines de Boost.Thread quedaria de la manera seguent:

1 boost ::mutex m ;

2

3 if ( i == 0 ) {

4 boost ::lock_guard < boost ::mutex >( m ) ;

5 // Seccio crıtica

6 }

Com pot observar-se, el bloqueig s’allibera quan l’execucio arriba al claudator que marca la fide l’ambit de l’if. D’aquesta manera s’aconsegueix una sintaxi mes compacta i menys propensaa errors.

5.5.11 Thread-safe Lazy Singleton amb Boost.Utility

El patro Singleton, tal com es descriu a [Gamma et al., 1994], no garanteix el seu funcionamentdavant la presencia de multiples threads. Un thread-safe lazy singleton es una classe d’una unicainstancia (singleton), que es crea sota demanda el primer moment que s’ha de fer servir (lazy) ique garanteix aquestes condicions davant la presencia de multiples fils d’execucio (thread-safe).Hi ha diverses maneres de construir aquest tipus d’objecte. La biblioteca Boost.Utility propor-ciona la funcio call once, que permet assegurar que una funcio (un tall de codi) s’executara unai nomes una vegada. S’ha fet servir per executar la creacio de la classe Main nomes un cop.

79

Page 95: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

80

Page 96: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Capıtol 6

Reimplementacio de l’ArquitecturaO2CA2 i Fase de Proves

Seguint els principis de les metodologies agils (vegeu 2.2), mentre s’anava analitzant el problema,dissenyant i implementant la solucio, aquesta es posava en practica per provar-la. Com s’haexplicat (seccio 2.1), durant el desenvolupament d’aquest projecte la feina que s’anava fent erautilitzada, paral·lelament, per anar reimplementant l’arquitectura O2CA2 utilitzant aquest nouframework.

Aixı, la reimplementacio de l’O2CA2 ha servit com a plataforma de proves del nou frameworkdesenvolupat: a mida que s’anaven elaborant nous components, aquests s’executaven per com-provar que el sistema complia els seus requeriments i que funcionava com s’esperava.

En aquest capıtol s’explica de forma qualitativa el disseny de l’arquitectura O2CA2 (seccio6.1), reimplementada sobre el sistema desenvolupat en aquest projecte i es repassa el proces decomprovacio dut a terme i els bugs trobats i solucionats durant les proves (seccio 6.2).

6.1 Una Ullada al Disseny de l’O2CA2

L’O2CA2 es una arquitectura dissenyada per a poder ser utilitzada en diferents sistemes robotics.Com pot observar-se a la figura 6.1, es divideix en tres moduls: el modul d’interfıcie del robot,el modul de percepcio i el modul de control.

81

Page 97: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Figura 6.1: Esquema de l’arquitectura O2CA2.

6.1.1 Modul d’Interfıcie del Robot

Aquest es l’unic modul que conte objectes que interactuen amb el maquinari directament. Estaformat basicament per dos tipus d’objectes: objectes sensor responsables de llegir les dadescaptades pels sensors fısics (p.e. cameres, sensors de pressio, sonars, bruixoles, giroscops, etc.)i objectes actuador encarregats d’enviar comandes als actuadors del robot (son tıpicamentmotors, pero poden ser d’altre tipus).

6.1.2 Modul de Percepcio

Aquest modul consta del conjunt d’objectes encarregats de fusionar les dades provinents delsobjectes sensors. Es generen aixı dades mes complexes, que poden ser utilitzades per els dife-rents comportaments per a generar respostes, o per generar esdeveniments. Com es mostra ala figura, en aquest modul hi ha un navegador, que s’encarrega de fusionar les dades de posicioi orientacio dels sensors i un detector d’obstacles. Tambe hi poden haver altres componentsque fusionin dades, com per exemple sistemes de posicionament absolut basats en un mapa osistemes de visio per computador.

6.1.3 Modul de Control

El modul de control fa servir la informacio generada pel modul de percepcio per determinarquina accio ha d’emprendre el robot. Aquest modul consta d’uns objectes anomenats comporta-ments, que estan dissenyats per a assolir un objectiu concret. Exemples tıpics de comportaments

82

Page 98: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

poden ser el comportament mantenir l’altitud o be el comportament mantenir l’orientacio. Ca-da comportament calcula una resposta del robot. Aquestes respostes son coordinades d’acordamb un conjunt de prioritats per un objecte anomenat coordinador, que genera una consignacomposada a partir de les respostes de cada comportament. El coordinador envia la consignacap al controlador de velocitat de baix nivell, que s’encarrega de controlar els motors del vehicled’acord amb aquesta.

En aquest modul s’hi troba tambe l’AAL, un objecte que permet a altres sistemes interactu-ar amb l’arquitectura rebent els esdeveniments que aquesta genera i enviant-hi accions, queconsisteixen basicament en activar o desactivar objectes. Aquesta AAL permet connectar l’ar-quitectura amb un sistema de control de missio que basicament realitzara un control discretbasat en esdeveniments i accions, seguint un pla de missio previament especificat per l’usuari.

6.2 Fase de Proves

6.2.1 Entorn i eines de debugging

Entorn

Totes les proves s’han dut a terme en plataformes UNIX, executant codi de la reimplementaciode l’O2CA2 sobre el sistema desenvolupat en aquest projecte. Per facilitar la descoberta isolucio d’errors s’ha compilat el codi incloent-hi la informacio de debug durant tot el proces dedesenvolupament.

Debugging amb gdb

L’IDE utilitzat proporciona un debugger amb interfıcie grafica basat en el l’eina gdb (GNUProject Debugger), que permet fixar breakpoints, executar pas a pas, veure traces d’execucio,etc.

Analisi de Paquets amb Wireshark

Per tracar l’enviament de missatges per xarxa s’ha fet servir el software Wireshark, que permetanalitzar el contingut dels paquets que s’envien (suporta multitud de protocols, entre ells TCP).D’aquesta manera s’han pogut analitzar les peticions i respostes enviades amb els diferentsprotocols i sistemes de comunicacio utilitzats (XMLoTCP, CORBA, ROS...) i detectar-hipossibles errors.

83

Page 99: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

6.2.2 Bugs trobats i solucions

A continuacio s’expliquen quins han estat els bugs mes rellevants descoberts durant la fase deproves, i quines mesures s’han aplicat per a solucionar-los.

Bug : Acces a Ports Serie amb LibSerial

Descripcio: aquest va ser un dels bugs mes difıcils de descobrir, i pot considerar-se un bug nocorrent de software∗, ja que es manifestava de manera aleatoria en circumstancies sense caprelacio aparent. L’error consistia en un acces il·legal a memoria (segmentation fault).

Descobriment: analitzant les traces proporcionades pel debugger, es va determinar que l’errorsempre es produıa despres d’una crida a una funcio de la classe SerialPortImpl (vegeu la lınia5 de la traca mostrada mes avall), que es part de la biblioteca d’acces a ports serie utilitzadafins al moment de descobrir aquest bug, LibSerial.

1 Thread 11 (Thread 0xb02f8b90 (LWP 10074)):

2 #0 0xb7f1e424 in __kernel_vsyscall ()

3 #1 0xb755d7a6 in nanosleep () from /lib/tls/i686/cmov/libc.so.6

4 #2 0xb759b14c in usleep () from /lib/tls/i686/cmov/libc.so.6

5 #3 0xb775136c in SerialPort :: SerialPortImpl :: ReadByte () from

6 /usr/lib/libserial.so.0

7 #4 0xb774ef33 in SerialPort :: ReadLine () from /usr/lib/libserial.so.0

8 #5 0x0828c974 in CSerialPort :: readLine (this=0xa045688 ,

9 msTimeout=0, lineTerminator =13 ’\r’) at

10 ../ src/core/io/dev/CSerialPort.cpp :532

Solucio: donat que la documentacio de LibSerial [P. Pagey, 2008] no donava cap informaciosobre aquest error ni es va trobar cap bug report que hi fes referencia, es va analitzar el codifont de la biblioteca. Es va determinar que l’error era causa d’un problema de disseny: LibSerialfa servir un signal per notificar que hi ha dades del port serie disponibles, emmagatzemades enun buffer que gestiona la biblioteca. Per defecte, els threads hereden la mateixa configuraciode signals del seu proces pare. Aixo provocava que sempre s’avises de l’arribada de dades atots els fils d’execucio en espera de dades d’algun port serie, i no nomes al fil encarregat delport serie on efectivament hi havia noves dades disponibles. Aixo provocava que, en ocasions,un fil d’execucio accedıs a un buffer buit que teoricament no hauria d’estar-ho, produint unacces il·legal a memoria. Com que es tractava d’un problema de disseny, va caldre descartarla biblioteca i elaborar una altra implementacio de l’acces a ports serie. Aquesta vegada es vaescollir Boost.Asio, que sı que suporta multiples fils d’execucio.

∗Els bugs no corrents de software son una classe de bugs considerats excepcionalment difıcils d’entendrei de reparar. N’hi ha de diversos tipus, que solen prendre el nom de cientıfics que han fet descobrimentscontraintuitius (p.e. heisenbug o schroedinbug).

84

Page 100: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Bug : Analisi Sintactic de Documents XML

Descripcio: es generen excepcions espontaniament indicant que cert document XML no s’hapogut carregar degut a un error sintactic.

Descobriment: tracant l’execucio i examinant les dades XML en el moment dels errors esva determinar que succeıen a causa de la presencia de caracters no imprimibles en els valorsd’alguns atributs. Va poder-se observar que l’error era degut a l’utilitzacio del tipus char deC++ a l’estructura d’un topic, el qual no estava contemplat. Aquesta situacio no era detectadacom a error per el compilador, ja que les cadenes de caracters de l’STL (objectes de tipusstd::string) poden assignar-se a dades de tipus char.

Solucio: canviar el tipus char per std::string, i afegir un comentari informatiu al programa pertal de recordar-ho als programadors.

Bug : Memoria Exhaurida amb el Paquet XML de les Biblioteques POCO

Descripcio: el programa finalitza en no capturar-se una excepcio llancada per el paquet XMLde les biblioteques POCO.

Descobriment: l’excepcio indica amb un missatge que s’ha exhaurit la memoria maxima dispo-nible de la biblioteca.

Solucio: comprovant la documentacio de les biblioteques POCO es va poder veure que aquestespermeten especificar amb un parametre el valor maxim per a la memoria que es fa servir enl’analisi sintactic dels documents XML. Aquest valor esta fixat a un valor per defecte si nos’especifica el contrari. Va caler fixar aquest parametre a un valor raonablement gran pera poder gestionar els documents del sistema, i capturar i tractar adequadament l’excepciogenerada per tal que el programa no finalitzes abruptament.

85

Page 101: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

86

Page 102: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Capıtol 7

Resultats

En aquest capıtol s’exposen els resultats obtinguts fins al moment amb el software elaborat enaquest projecte.

Una vegada el sistema desenvolupat ha estat provat amb la reimplementacio de l’arquitecturaO2CA2, se n’ha fet el desplegament sobre els dos robots submarins que hi ha actualment alCIRS: l’Ictineu, construıt el 2006, i l’Sparus, desenvolupat aquest 2010. A mes, esta previst quel’arquitectura de control que es desenvolupara per al nou robot submarı que s’esta construint,el GIRONA 500, utilitzi tambe el software elaborat en aquest projecte.

Amb els robots Ictineu i Sparus executant aquest software, s’han realitzat diverses activitatsque han posat a prova el sistema i n’han demostrat la fiabilitat, robustesa i bon funcionament.Tot seguit s’explica quines han estat aquestes activitats.

7.1 Desplegament del Sistema

7.1.1 Desplegament al Robot Ictineu

El robot Ictineu (mostrat a la figura 7.1) va ser construıt l’any 2006 per participar a la primeraedicio del SAUC-E, la primera competicio de robotica submarina disputada a Europa, i hi vaquedar campio [Ribas et al., 2007]. Tot i haver estat construıt inicialment per a participaren una competicio d’estudiants [Hernandez et al., 2006], l’Ictineu va resultar ser una moltbona plataforma per dur a terme experiments: des de la seva construccio ha participat en elsprojectes de recerca d’ambit nacional AIRSUB i Inspecsub, aixı com en una col·laboracio ambl’empresa Ecohydros per fer un estudi del musclo zebra al panta de Mequinenca i en multitudd’altres experiments, tant a la piscina de proves del CIRS com en entorns naturals.

El robot esta equipat amb un conjunt de sensors format per una camera a color de visio frontal,una camera en blanc i negre orientada cap al fons, una unitat de referencia inercial que inclou

87

Page 103: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Figura 7.1: El robot Ictineu operant a la piscina del CIRS.

un giroscop de fibra optica de Tritech que permet coneixer la orientacio relativa del vehicle, unsonar de formacio d’imatges model MiniKing de Tritech, una ecosonda d’Airmar i un DopplerVelocity Log (DVL) de Sontek, dispositiu basat en l’efecte Doppler que permet mesurar lavelocitat del vehicle respecte el fons o respecte l’aigua i que inclou una bruixola, inclinometres,un sensor de pressio i un altımetre.

Aquest robot feia servir la ja esmentada arquitectura O2CA2, pero implementada fent servir elsistema base antic [Hernandez, 2005], que funcionava amb CORBA. Com s’ha explicat (seccio2.1), paral·lelament al desenvolupament d’aquest projecte, s’ha reimplementat l’arquitecturaantiga sobre el nou framework desenvolupat.

7.1.2 Desplegament al Robot Sparus

El robot Sparus (mostrat a la figura 7.2) ha estat construıt per afrontar l’edicio d’enguany dela competicio SAUC-E, on s’ha pogut revalidar l’exit aconseguit el 2006, darrera edicio on hiva participar un equip d’aquesta universitat.

El seu disseny es en forma de torpede, i incorpora un sonar de formacio d’imatges model Micronde Tritech, un DVL de LinkQuest, una unitat inercial model MTi de XSens Technologies, unaecosonda, dues cameres i sensors de presencia d’aigua, temperatura, pressio i tensio.

S’hi ha desplegat el sistema satisfactoriament, afrontant amb exit la competicio SAUC-E 2010i diversos experiments que s’esmentaran mes avall.

88

Page 104: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Figura 7.2: El robot Sparus executant una missio.

7.2 Experiments Realitzats

Campions del SAUC-E 2010

Del 28 de juny al 4 de juliol de 2010, un equip format per estudiants de la Universitat deGirona va prendre part en l’edicio del 2010 de la competicio d’estudiants europea de roboticasubmarina, el SAUC-E. En aquesta competicio, disputada enguany a la localitat italiana de LaSpezzia, hi van prendre part 10 equips d’estudiants d’arreu d’Europa. La competicio consisteixen fer executar una missio a un robot submarı de manera completament autonoma, senseinvervencio humana, i acomplint sequencialment les seguents tasques:

1. Sortir des d’un moll del port i passar per una porta de validacio.

2. Detectar una canonada i fer-ne un seguiment.

3. Passar per una segona porta de validacio.

4. Detectar un objectiu que esta lligat al fons marı amb una corda i alliberar-lo tallantaquesta corda.

5. Fer el seguiment d’una paret.

6. Detectar un emissor acustic situat en algun lloc de l’entorn submarı.

7. Dirigir-se fins la posicio de l’emissor i emergir.

A la figura 7.3 es mostra un model 3D de l’entorn on calia portar a terme aquestes tasques.

L’equip que mes tasques aconsegueix realitzar amb exit es el que guanya. Aquest any un equipd’estudiants de la Universitat de Girona hi va participar amb el robot Sparus, construıt de nou

89

Page 105: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Figura 7.3: Entorn de la competicio SAUC-E 2010.

per afrontar la competicio. El robot era controlat per una arquitectura desenvolupada sobreel framework elaborat en aquest projecte. Fou l’equip gironı el que va fer un millor paper ala competicio, i per tant hi va quedar campio. Es va repetir aixı l’exit aconseguit a l’ediciodel 2006 per un altre equip d’estudiants d’aquesta universitat, l’altra unica edicio on hi haparticipat un equip gironı.

A la figura 7.4 es pot veure dos membres de l’equip en un moment de la competicio.

Figura 7.4: Dos membres de l’equip gironı al SAUC-E 2010.

L’equip, del qual se’n pot veure una fotografia a la figura 7.5 feta durant la competicio, constavadels seguents membres:

• Natalia Hurtos (Enginyer Informatic), estudiant de doctorat UdG

• Aggelos Mallios (Enginyer Informatic), estudiant de doctorat UdG

90

Page 106: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Figura 7.5: L’equip campio del SAUC-E 2010, format per estudiants de la Universitat deGirona.

• Sebastian Carreno (Enginyer Informatic), estudiant de doctorat UdG

• Xavier Fuster (Enginyer Informatic), estudiant master MIIACS UdG

• Simo Cusı (Enginyer Industrial), estudiant master MIIACS UdG

• Ricard Campos (Enginyer Informatic), estudiant master MIIACS UdG

• Chee Sing Lee (Enginyer Electronic), estudiant master VIBOT UdG

• Enric Galceran (Enginyer Tecnic Informatic), estudiant Enginyeria Informatica UdG

• Arnau Carrera (Enginyer Tecnic Informatic), estudiant Enginyeria Informatica UdG

Experiments a la Marina Abandonada Fluvia Nautic

Durant el juliol de 2010, despres de la competicio SAUC-E, es van realitzar alguns experimentsamb el robot Sparus i el seu nou sistema de software a la marina abandonada Fluvia Nautic delmunicipi de Sant Pere Pescador (Girona). Els experiments eren un assaig general dels que esvan dur a terme al cap de pocs dies a les illes Acores (vegeu el proxim apartat), i van consistiren l’execucio de diverses trajectories de forma autonoma i es van dur a terme satisfactoriament.A la figura 7.6 pot veure’s el robot Sparus operant dins la marina abandonada.

Experiments a les Illes Acores

Amb motiu d’una reunio de la xarxa europea de recerca FreeSubNet, de la qual forma partel Laboratori de Robotica Submarina, a finals de juliol de 2010 es van realitzar una serie

91

Page 107: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Figura 7.6: El robot Sparus realitzant una missio autonoma a la marina abandonada FluviaNautic.

d’experiments a les illes Acores (Portugal), al bell mig de l’ocea Atlantic, amb el robot Sparus.Els experiments van consistir en l’execucio de diverses trajectories a uns 17 m. de profunditat.A la figura 7.8 pot veure’s el robot Sparus realitzant una de les trajectories, passant a prop d’unsubmarinista. A la figura 7.9 s’hi pot veure la representacio d’una de les trajectories efectuades.

Experiments amb el Robot Ictineu

Amb el robot Ictineu s’han dut tambe a terme diversos experiments a la piscina del CIRS. Elsexperiments han consistit en la comprovacio del sistema de navegacio i en l’execucio de diversestrajectories de manera autonoma.

El futur: el GIRONA 500

Recentment, el Laboratori de Robotica Submarina esta portant a terme, juntament amb altresuniversitats, dos projectes de recerca: el RAUVI, de caire nacional, i el TRIDENT, un projected’ambit europeu.

El projecte RAUVI consisteix en desenvolupar un robot capac d’executar una missio d’inter-vencio en entorns submarins. La missio pot resumir-se en dos passos: inspeccio i intervencio.Primerament, el vehicle explora, autonomament, una regio d’interes, prenent dades visuals iacustiques sincronitzades amb la navegacio del robot. A continuacio, el robot emergeix, i lainformacio recollida es descarregada a l’estacio base, on es fa una reconstruccio per ordinadorde la regio explorada. Fent servir una interfıcie huma-robot, un operador identifica un objected’interes i descriu una tasca que cal acomplir. Tot seguit, el robot navega altre vegada de

92

Page 108: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Figura 7.7: El robot Sparus a punt d’iniciar una trajectoria autonomament a les illes Acores.

Figura 7.8: El robot Sparus realitzant una trajectoria autonomament a les illes Acores.

93

Page 109: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Figura 7.9: Trajectoria realitzada per el robot Sparus a les illes Acores (unitats dels eixos enmetres).

manera autonoma fins a la regio d’interes, identica l’objecte i executa la tasca d’intervenciomitjancant un actuador mecanic (i.e. un brac robotic). La figura 7.10 mostra el GIRONA 500,el robot que s’esta construint per a executar les tasques d’aquest projecte.

El projecte TRIDENT proposa una nova metodologia per realitzar tasques d’intervencio so-ta l’aigua, amb diverses aplicacions potencials, com arqueologia submarina, oceanografia iindustries marines, anant mes enlla dels metodes actuals, tıpicament basats en sistemes tri-pulats.

El projecte te per objectiu fer servir un equip de dos robots cooperatius amb habilitats comple-mentaries, una nau de superfıcie autonoma (ASC) i un robot submarı autonom d’intervencio(I-AUV) equipat amb un manipulador. La metodologia es basa en dos passos. En el primer,l’I-AUV es desacoblat de l’ASC per realitzar una inspeccio conjunta: l’I-AUV pren dades delfons mentre que l’ASC proporciona georeferenciacio a tots dos sistemes (les unitats GPS nofuncionen sota l’aigua, i l’ASC s’encarrega de fer servir els dispositius adequats per aconseguiraquestes dades). Les dades preses son pujades cap a la superfıcie per l’I-AUV, que s’acoblaamb l’ASC. A continuacio es selecciona un punt d’interes de la ruta que el robot del fons haseguit. L’I-AUV s’hi dirigeix, i a partir d’aquı porta a terme una navegacio i una manipulaciod’un objectiu seleccionat previament, tot de manera autonoma. La figura 7.11 il·lustra aquestprocediment, que sera dut a terme tambe amb el robot GIRONA 500.

El projecte RAUVI fa incıs en la construccio del robot i l’execucio autonoma de trajectories,mentre que el projecte TRIDENT aprofundeix mes en la robotica col·laborativa i en la in-

94

Page 110: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Figura 7.10: Model 3D del robot GIRONA 500, encara en construccio. A l’esquerra, vista deperfil amb el brac robotic al modul inferior. A la dreta, vista general.

tel·ligencia artifical necessaria per a realitzar manipulacions autonomament. Esta previst queel robot GIRONA 500 pugui arribar a profunditats de fins a 500 metres.

Figura 7.11: Metodologia del projecte TRIDENT.

95

Page 111: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

96

Page 112: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Capıtol 8

Conclusio

Aquest capıtol tanca la memoria fent un resum de les tasques dutes terme en el projecte (seccio8.1) i exposant les conclusions que se’n poden extreure (seccio 8.2). A continuacio proposaalguns treballs futurs que poden realitzar-se un cop finalitzat aquest projecte (seccio 8.3).

8.1 Resum

En aquest projecte, iniciat amb la decisio de desenvolupar una nova solucio software per aelaborar sistemes de control per a robots que satisfes els requeriments del Laboratori de RoboticaSubmarina, s’han dut a terme les seguents tasques.

Inicialment, s’ha dut a terme una planificacio del projecte (capıtol 2). En aquesta planificacios’ha fet una contextualitzacio del projecte, indicant quines restriccions de temps i de recursoscalia tenir en compte; s’ha seleccionat una metodologia de desenvolupament de software agil,per comencar a poder fer proves i obtenir resultats des dels primers moments del proces; s’hafet la temporitzacio de les fases del desenvolupament i s’han seleccionat les eines que s’hanutilitzat.

A continuacio s’ha realitzat l’analisi (capıtol 3), especificant els requeriments funcionals i nofuncionals del sistema fent servir com a ajuda l’analisi de casos d’us, que tambe ha servit peridentificar les funcions del sistema i elaborar l’especificacio funcional.

Un cop obtinguda l’especificacio funcional, s’ha dissenyat una solucio que complıs aquestaespecificacio (capıtol 4). Per fer-ho, ha calgut especificar l’estructura dels documents XMLque s’utilitzen per representar dades dins el sistema. S’ha especificat tambe l’estructura delsfitxers de configuracio i s’ha dissenyat un protocol de comunicacio per a intercanviar dadesentre components del sistema que es troben en diferents nodes d’una xarxa de computadors.

Havent dissenyat la solucio, se n’ha dut a terme la implementacio (capıtol 5). En aquest puntdel projecte s’han aplicat les directrius d’una guia d’estil per a obtenir un codi mes uniforme i

97

Page 113: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

mes facil de mantenir; s’ha fet servir Doxygen com a eina per fer la documentacio del codi; s’hafet us de diverses biblioteques de programacio de terceres parts per a solucionar les necessitatsde programacio mes comunes i tambe se n’han elaborat de noves; finalment, s’ha fet front adiversos detalls d’implementacio, solucionant-ne alguns fent servir caracterıstiques avancadesdel llenguatge C++ com per exemple programacio generica o pointers to members.

Una vegada feta la implementacio del sistema, s’ha realitzat una reimplementacio de l’arquitec-tura de control O2CA2, ja disponible al laboratori, fent servir el nou sistema base desenvolupat.Aquesta reimplementacio s’ha fet servir per posar a prova el nou sistema i detectar-hi errorsque ha calgut solucionar (capıtol 6).

Quan s’ha tingut a punt la nova implementacio de l’arquitectura O2CA2, se n’ha fet el des-plegament sobre els robots submarins Ictineu i Sparus (capıtol 7). Amb el robot Ictineu s’handut a terme experiments a la piscina de proves del CIRS. Amb el robot Sparus, construıt perprendre part a l’edicio 2010 del SAUC-E, s’ha participat en aquesta competicio, quedant-hicampio l’equip de la Universitat de Girona. Tambe amb el robot Sparus s’han realitzat experi-ments a les illes Acores, al bell mig de l’ocea Atlantic, duent a terme un reconeixement del fonsmarı a 17 m. de profunditat. S’ha previst tambe que el nou robot submarı GIRONA 500, quesera capac d’arribar fins a 500 m. de profunditat, faci servir el sistema desenvolupat en aquestprojecte.

8.2 Conclusions

Aquest projecte ha acomplert amb exit el proposit (exposat a la seccio 1.4) de desenvolu-par una solucio de software que permeti desenvolupar diverses arquitectures de control per adiferents robots, satisfent els requeriments del Laboratori de Robotica Submarina. S’ha fetsatisfactoriament el desplegament de la solucio sobre els robots submarins del laboratori.

Responent un a un als objectius especıfics de la seccio 1.4, s’ha aconseguit:

• Maximitzar el desacoblament. La solucio desenvolupada proporciona un alt grau dedesacoblament amb els nous components de software que es desenvolupen fent-la servircom a base, gracies a l’especificacio funcional elaborada i als criteris de disseny aplicats.

• Facilitat d’us. La solucio elaborada permet que desenvolupar nous components desoftware per als robots del laboratori i per a altres robots sigui senzill, i que permeti alsseus desenvolupadors centrar-se en la tasca final del component sense haver de fer fronta questions de software secundaries.

• Robustesa i fiabilitat. Les proves, experiments i missons duts a terme amb els robotsIctineu i Sparus en diveros entorns, tant artificials com naturals, durant llargs perıodesde temps, demostren que el sistema desenvolupat es robust i fiable, i que respon satis-factoriament durant l’execucio d’una missio per part d’un robot.

98

Page 114: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

• Participacio al SAUC-E 2010. S’ha participat a la competicio europea SAUC-E 2010,fent servir el software desenvolupat, amb l’equip de la Universitat de Girona, i s’hi haquedat campio.

• Desplegament. El software desenvolupat s’ha desplegat amb exit sobre els robots sub-marins del Laboratori de Robotica Submarina, i es preveu que se’n faci us tambe al nourobot Generic Intelligent Robot Operated and Navigated Autonomously (GIRONA) 500,actualment en proces de desenvolupament.

• Documentacio. S’ha elaborat una bona documentacio per tal que serveix com a re-ferencia a futurs programadors que desenvolupin software basat en aquest sistema.

8.3 Treballs futurs

A continuacio es proposen diversos treballs futurs que poden dur-se a terme un cop finalitzataquest projecte, a fi i efecte de donar continuıtat a la feina que s’ha fet:

• Validacio de documents XML: actualment cal analitzar sintacticament els documentsXML, crear un model Document Object Model (DOM) i recorrer-lo per determinar sil’estructura d’un document determinat compleix l’especificacio explicada a la seccio 4.4.Fora bo estudiar si, partint d’aquesta estructura estatica, seria viable fer servir un metodede validacio de documents XML, com per exemple XML Schema.

• Base de dades de logs: actualment el sistema desenvolupat desa els logs en un directoriespecificat, classificant els logs de cada missio en diferents subdirectoris. Seria interessantdesenvolupar una base de dades per indexar i facilitar l’acces i la manipulacio d’aquestsfitxers de log.

• Biblioteca de programacio per a terceres parts: la reimplementacio de l’arquitec-tura O2CA2 s’ha fet integrant el codi font del framework desenvolupat en aquest projectei el de l’arquitectura O2CA2 en si. Aquesta ha estat una via satisfactoria per al laboratori,pero seria interessant poder distribuir i fer us del framework mitjancant una bibliotecade programacio, permetent aixı desacoblar els components d’una arquitectura de controldels del sistema base.

99

Page 115: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

100

Page 116: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Bibliografia

[Atwood, 2009] Atwood, J. (2009). Don’t Reinvent The Wheel, Unless You Planon Learning More About Wheels. http://www.codinghorror.com/blog/2009/02/

dont-reinvent-the-wheel-unless-you-plan-on-learning-more-about-wheels.html -Consultat l’agost de 2010.

[Baker, 1997] Baker, S. (1997). CORBA Distributed Objects Using Orbix. ACM Press Booksand Addison-Wesley.

[Batlle et al., 2004] Batlle, J., Ridao, P., Garcia, R., Carreras, M., Cufi, X., El-Fakdi, A., Ribas,D., Nicosevici, T., and Batlle, E. (2004). URIS: Underwater Robotic Intelligent System,volume Chapter 11, pp: 177-203. Instituto de Automatica Industrial, Consejo Superior deInvestigaciones Cientificas, first edition.

[Beck et al., 2001] Beck, K., Beedle, M., van Bennekum, A., Cockburn, A., Cunningham,W., Fowler, M., Grenning, J., Highsmith, J., Hunt, A., Jeffries, R., Kern, J., Marick, B.,C.Martin, R., Mellor, S., Schwaber, K., Sutherland, J., and Thomas, D. (2001). Agile Mani-festo. http://agilemanifesto.org/ - Consultat l’octubre de 2009.

[Buschmann et al., 1996] Buschmann, F., Meunier, R., andPeter Sommerlad, H. R., and Stal,M. (1996). Pattern-Oriented Software Architecture Volume 1: A System of Patterns. JohnWiley & Sons.

[Buzan, 1996] Buzan, T. (1996). The Mind Map Book. Penguin Books.

[CARMEN, 2010] CARMEN (2010). Introduction - What’s Carmen? http://carmen.

sourceforge.net/intro.html - Consultat l’agost de 2010.

[Cline, 2010] Cline, M. (2010). [10.6] Should my constructors use “initialization lists” or “assig-nment”? http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6 - Consultatel desembre de 2009.

[Cline et al., 1999] Cline, M., Lomow, G., and Girou, M. (1999). C++ FAQs. Addison-Wesley.

[Erl, 2004] Erl, T. (2004). Service-Oriented Architecture: A Field Guide to Integrating XMLand Web Services. Prentice Hall.

[ESA, 2004] ESA (2004). ESA - CDF - Interview with Massimo Bandecchi What role does theCDF play in ESA. http://www.esa.int/esaMI/CDF/SEMBNMYV1SD_0.html - Consultat eldesembre de 2009.

101

Page 117: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

[Gamma et al., 1994] Gamma, E., Helm, R., Johnson, R., and Vlissides, J. (1994). DesignPatterns: Elements of Reusable Object-Oriented Software. Addison-Wesley.

[Geotechnical Software Services, 2008] Geotechnical Software Services (2008). C++ Program-ming Style Guidelines. http://geosoft.no/development/cppstyle.html - Consultat elnovembre de 2009.

[Google, Inc., 2010] Google, Inc. (2010). Google C++ Style Guide. http://

google-styleguide.googlecode.com/svn/trunk/cppguide.xml - Consultat el maig de2010.

[Hernandez, 2005] Hernandez, E. (2005). Disseny i Implementacio d’una Arquitectura SoftwareDistribuıda i Orientada a Objectes amb Suport per l’Execucio en Temps Real. Aplicacio aun Robot Submarı. Master’s thesis, Universitat de Girona.

[Hernandez et al., 2006] Hernandez, E., Ridao, P., Carreras, M., Ribas, D., and Palomeras,N. (2006). Ictineu AUV, un Robot per a Competir. In 9e Congres Catala d’Intel·ligenciaArtificial.

[id Software, Inc., 2010] id Software, Inc. (2010). id Software C++ Coding Conventions. http://www.geeks3d.com/20081111/id-software-c-coding-conventions/ - Consultat l’agostde 2010.

[IEEE Computer Society, 1998] IEEE Computer Society (1998). IEEE Recommended Practicefor Software Requirements Specifications.

[IEEE Computer Society, 2009] IEEE Computer Society (2009). IEEE Standard for Informa-tion Technology–Systems Design–Software Design Descriptions.

[Kusiak, 1993] Kusiak, A. (1993). Concurrent Engineering: Automation, Tools and Techniques.Andrew Kusiak.

[Llamas, 2005] Llamas, J. (2005). Using Interfaces in C++. http://www.codeguru.com/cpp/cpp/cpp_mfc/oop/article.php/c9989 - Consultat l’octubre de 2009.

[McConnell, 2004] McConnell, S. (2004). Code Complete: A Practical Handbook of SoftwareConstruction. Microsoft Press.

[Microsoft Corporation, 2010] Microsoft Corporation (2010). Microsoft robotics. http://

msdn.microsoft.com/en-us/robotics/default.aspx - Consultat l’agost de 2010.

[MRPT, 2010] MRPT (2010). The Mobile Robot Programming Toolkit. http://www.mrpt.

org/ - Consultat l’agost de 2010.

[NASA, 2008] NASA (2008). Jpl team x. http://jplteamx.jpl.nasa.gov/ - Consultat eldesembre de 2009.

[Newman, 2009] Newman, P. (2009). Introduction to Programming with MOOS.http://www.robots.ox.ac.uk/~pnewman/MOOSDocumentation/ProgrammingWithMOOS/

latex/ProgrammingWithMOOS.pdf - Consultat l’agost de 2010.

102

Page 118: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

[Nof, 1999] Nof, S. Y. (1999). Handbook of Industrial Robotics. John Wiley & Sons, 2nd edition.

[Orca, 2010] Orca (2010). Orca: Components for Robotics. http://orca-robotics.

sourceforge.net/ - Consultat l’agost de 2010.

[P. Pagey, 2008] P. Pagey, M. (2008). LibSerial Documentation. http://libserial.

sourceforge.net/ - Consultat l’agost de 2010.

[Palomeras et al., 2008] Palomeras, N., Ridao, P., Carreras, M., and Silvestre, C. (2008).Towards a Mission Control Language for AUVs. In Proceedings of the 17th World Con-gress. The International Federation of Automatic Control.

[Perez, 2002] Perez, O. (2002). Construccio d’un Marc de Treball per l’Elaboracio de Sistemesde Control Distribuıts en Temps Real. Master’s thesis, Universitat de Girona.

[POCO C++ Libraries, 2010] POCO C++ Libraries (2010). POCO C++ Libraries - ReferenceLibrary. http://pocoproject.org/docs/ - Consultat l’agost del 2010.

[Ribas et al., 2007] Ribas, D., Palomeras, N. P., Ridao, P., Carreras, M., and Hernandez, E.(2007). Ictineu AUV wins the first SAUC-E competition. In IEEE International Conferenceon Robotics and Automation.

[Ridao et al., 2001] Ridao, P., Batlle, J., and Carreras, M. (2001). O2CA2. A New Object-Oriented Control Architecture for Autonomy. The Reactive Layer. Control Engineering inPractice Journal.

[ROS.org, 2010] ROS.org (2010). ROS/Introduction. http://www.ros.org/wiki/ROS/

Introduction - Consultat el juliol de 2010.

[Spolsky, 2000a] Spolsky, J. (2000a). Painless Functional Specifications - Part 2: What’s aSpec? Joel on Software.

[Spolsky, 2000b] Spolsky, J. (2000b). The Joel Test: 12 Steps to Better Code. Joel on Software.

[Sutter, 2009] Sutter, H. (2009). More Exceptional C++. Addison-Wesley.

[Sutter and Alexandrescu, 2005] Sutter, H. and Alexandrescu, A. (2005). C++ Coding Stan-dards: 101 Rules, Guidelines, and Best Practices. Addison-Wesley.

[The Orocos Project, 2010] The Orocos Project (2010). About the OROCOS Project — TheOrocos Project. http://www.orocos.org/orocos/whatis - Consultat l’agost de 2010.

[The Player Project, 2010] The Player Project (2010). The Player Project. http://

playerstage.sourceforge.net/ - Consultat el juliol de 2010.

[van Heesch, 2009] van Heesch, D. (2009). Doxygen. http://www.stack.nl/~dimitri/

doxygen/index.html - Consultat el juliol de 2010.

[van Vliet, 2000] van Vliet, H. (2000). Software Engineering: Principles and Practice, 2ndEdition. John Wiley & Sons.

103

Page 119: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

[W3C, 1999] W3C (1999). XML Path Language (XPath). http://www.w3.org/TR/xpath/.

[YARP, 2010] YARP (2010). What exactly is YARP? http://eris.liralab.it/yarpdoc/

what_is_yarp.html - Consultat el juliol de 2010.

104

Page 120: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

Apendix A

Codi Font de la ClasseCGenericDataManip

105

Page 121: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

1 /*

2 * CGenericDataManip.h

3 *

4 * Created on: Abr 7, 2010

5 * Author: Enric Galceran

6 */

7

8 #ifndef CGENERICDATAMANIP_H_

9 #define CGENERICDATAMANIP_H_

10

11 #include <string >

12 #include <stdexcept >

13 #include <map >

14 #include <list >

15 #include <sstream >

16 #include <Eigen/Eigen >

17 #include "CXmlDataManip.h"

18

19 template < typename D >

20 class CGenericDataManip {

21

22 public:

23

24 typedef D DataType ;

25

26 CGenericDataManip( const std:: string& name ):

27 name_( name ),

28 integers_ (),

29 reals_ (),

30 strings_ (),

31 booleans_ (),

32 vectors_ (),

33 matrices_ (),

34 wordArrays_ (),

35 itemNames_ ()

36 { }

37

38

39

40 virtual

41 ~CGenericDataManip ()

42 { }

43

44

45

46 void

47 loadXmlString( const std:: string& xmlDocument )

106

Page 122: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

48 throw ( std:: runtime_error )

49 {

50 CXmlDataManip dm ;

51 dm.loadXmlString( xmlDocument ) ;

52 for ( typename IntegersMap :: const_iterator i =

integers_.begin(); i != integers_.end(); ++i ) {

53 data_ .*(i->second) = dm.getInteger( getName ()

+ "/" + i->first ) ;

54 }

55 for ( typename RealsMap :: const_iterator i = reals_.

begin (); i != reals_.end(); ++i ) {

56 data_ .*(i->second) = dm.getReal( getName () + "

/" + i->first ) ;

57 }

58 for ( typename StringsMap :: const_iterator i = strings_

.begin (); i != strings_.end(); ++i ) {

59 data_ .*(i->second) = dm.getString( getName () +

"/" + i->first ) ;

60 }

61 for ( typename BooleansMap :: const_iterator i =

booleans_.begin(); i != booleans_.end(); ++i ) {

62 data_ .*(i->second) = dm.getBoolean( getName ()

+ "/" + i->first ) ;

63 }

64 for ( typename VectorsMap :: const_iterator i = vectors_

.begin (); i != vectors_.end(); ++i ) {

65 data_ .*(i->second) = dm.getVector( getName () +

"/" + i->first ) ;

66 }

67 for ( typename MatricesMap :: const_iterator i =

matrices_.begin(); i != matrices_.end(); ++i ) {

68 data_ .*(i->second) = dm.getMatrix( getName () +

"/" + i->first ) ;

69 }

70 for ( typename WordArraysMap :: const_iterator i =

wordArrays_.begin (); i != wordArrays_.end(); ++i )

{

71 data_ .*(i->second) = dm.getWordArray( getName

() + "/" + i->first ) ;

72 }

73 }

74

75

76

77 std:: string

78 getXmlString () const

79 throw ( std:: runtime_error )

80 {

107

Page 123: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

81 CXmlDataManip dm ;

82 dm.createEmptyDocument( getName () ) ;

83 for ( typename IntegersMap :: const_iterator i =

integers_.begin(); i != integers_.end(); ++i ) {

84 dm.addInteger( getName (), i->first , data_ .*(i

->second) ) ;

85 }

86 for ( typename RealsMap :: const_iterator i = reals_.

begin (); i != reals_.end(); ++i ) {

87 dm.addReal( getName (), i->first , data_ .*(i->

second) ) ;

88 }

89 for ( typename StringsMap :: const_iterator i = strings_

.begin (); i != strings_.end(); ++i ) {

90 dm.addString( getName (), i->first , data_ .*(i->

second) ) ;

91 }

92 for ( typename BooleansMap :: const_iterator i =

booleans_.begin(); i != booleans_.end(); ++i ) {

93 dm.addBoolean( getName (), i->first , data_ .*(i

->second) ) ;

94 }

95 for ( typename VectorsMap :: const_iterator i = vectors_

.begin (); i != vectors_.end(); ++i ) {

96 dm.addVector( getName (), i->first , data_ .*(i->

second) ) ;

97 }

98 for ( typename MatricesMap :: const_iterator i =

matrices_.begin(); i != matrices_.end(); ++i ) {

99 dm.addMatrix( getName (), i->first , data_ .*(i->

second) ) ;

100 }

101 for ( typename WordArraysMap :: const_iterator i =

wordArrays_.begin (); i != wordArrays_.end(); ++i )

{

102 dm.addWordArray( getName (), i->first , data_ .*(

i->second) ) ;

103 }

104 return dm.getXmlString () ;

105 }

106

107

108

109 std:: string

110 getName () const

111 {

112 return name_ ;

113 }

108

Page 124: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

114

115

116

117 // TODO: This is evil , at least in our particular

multithreaded environment. MUST BE TESTED.

118 DataType&

119 data()

120 {

121 return data_ ;

122 }

123

124

125

126 virtual

127 std:: string

128 stringifyNames () const

129 {

130 std:: ostringstream ss ;

131 for ( typename IntegersMap :: const_iterator i =

integers_.begin(); i != integers_.end(); ++i ) {

132 ss << i->first << "\t" ;

133 }

134 for ( typename RealsMap :: const_iterator i = reals_.

begin (); i != reals_.end(); ++i ) {

135 ss << i->first << "\t" ;

136 }

137 for ( typename StringsMap :: const_iterator i = strings_

.begin (); i != strings_.end(); ++i ) {

138 ss << i->first << "\t" ;

139 }

140 for ( typename BooleansMap :: const_iterator i =

booleans_.begin(); i != booleans_.end(); ++i ) {

141 ss << i->first << "\t" ;

142 }

143 for ( typename VectorsMap :: const_iterator i = vectors_

.begin (); i != vectors_.end(); ++i ) {

144 ss << i->first << "\t" ;

145 }

146 for ( typename MatricesMap :: const_iterator i =

matrices_.begin(); i != matrices_.end(); ++i ) {

147 ss << i->first << "\t" ;

148 }

149 for ( typename WordArraysMap :: const_iterator i =

wordArrays_.begin (); i != wordArrays_.end(); ++i )

{

150 ss << i->first << "\t" ;

151 }

152 return ss.str() ;

109

Page 125: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

153 }

154

155

156

157 virtual

158 std:: string

159 stringifyValues () const

160 {

161 std:: ostringstream ss ; // TODO: set output format ,

fixed point precision , etc...

162 for ( typename IntegersMap :: const_iterator i =

integers_.begin(); i != integers_.end(); ++i ) {

163 ss << i->second << "\t" ;

164 }

165 for ( typename RealsMap :: const_iterator i = reals_.

begin (); i != reals_.end(); ++i ) {

166 ss << i->second << "\t" ;

167 }

168 for ( typename StringsMap :: const_iterator i = strings_

.begin (); i != strings_.end(); ++i ) {

169 ss << i->second << "\t" ;

170 }

171 for ( typename BooleansMap :: const_iterator i =

booleans_.begin(); i != booleans_.end(); ++i ) {

172 ss << i->second << "\t" ;

173 }

174 for ( typename VectorsMap :: const_iterator i = vectors_

.begin (); i != vectors_.end(); ++i ) {

175 ss << i->second << "\t" ;

176 }

177 for ( typename MatricesMap :: const_iterator i =

matrices_.begin(); i != matrices_.end(); ++i ) {

178 ss << i->second << "\t" ;

179 }

180 for ( typename WordArraysMap :: const_iterator i =

wordArrays_.begin (); i != wordArrays_.end(); ++i )

{

181 ss << i->second << "\t" ;

182 }

183 return ss.str() ;

184 }

185

186 protected:

187 DataType data_ ;

188

189 void

190 addItem( const std:: string& name ,

191 int DataType ::* value )

110

Page 126: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

192 throw ( std:: runtime_error )

193 {

194 addItem( name , value , integers_ ) ;

195 }

196

197

198

199 void

200 addItem( const std:: string& name ,

201 double DataType ::* value )

202 throw ( std:: runtime_error )

203 {

204 addItem( name , value , reals_ ) ;

205 }

206

207

208

209 void

210 addItem( const std:: string& name ,

211 std:: string DataType ::* value )

212 throw ( std:: runtime_error )

213 {

214 addItem( name , value , strings_ ) ;

215 }

216

217

218

219 void

220 addItem( const std:: string& name ,

221 bool DataType ::* value )

222 throw ( std:: runtime_error )

223 {

224 addItem( name , value , booleans_ ) ;

225 }

226

227

228

229 void

230 addItem( const std:: string& name ,

231 Eigen:: VectorXd DataType ::* value )

232 throw ( std:: runtime_error )

233 {

234 addItem( name , value , vectors_ ) ;

235 }

236

237

238

239 void

111

Page 127: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

240 addItem( const std:: string& name ,

241 Eigen:: MatrixXd DataType ::* value )

242 throw ( std:: runtime_error )

243 {

244 addItem( name , value , matrices_ ) ;

245 }

246

247

248

249 void

250 addItem( const std:: string& name ,

251 std::vector < std:: string > DataType ::* value

)

252 throw ( std:: runtime_error )

253 {

254 addItem( name , value , wordArrays_ ) ;

255 }

256

257 private:

258

259 typedef std::map < std::string , int DataType ::* > IntegersMap ;

260 typedef std::map < std::string , double DataType ::* > RealsMap ;

261 typedef std::map < std::string , std:: string DataType ::* >

StringsMap ;

262 typedef std::map < std::string , bool DataType ::* > BooleansMap

;

263 typedef std::map < std::string , Eigen:: VectorXd DataType ::* >

VectorsMap ;

264 typedef std::map < std::string , Eigen:: MatrixXd DataType ::* >

MatricesMap ;

265 typedef std::map < std::string , std::vector < std:: string >

DataType ::* > WordArraysMap ;

266

267 const std:: string name_ ;

268

269 IntegersMap integers_ ;

270 RealsMap reals_ ;

271 StringsMap strings_ ;

272 BooleansMap booleans_ ;

273 VectorsMap vectors_ ;

274 MatricesMap matrices_ ;

275 WordArraysMap wordArrays_ ;

276

277 std::list < std:: string > itemNames_ ;

278

279 template < typename ValueType , typename ContainerType >

280 void

281 addItem( const std:: string& name ,

112

Page 128: Projecte/Treball de Final de Carrerarobots.engin.umich.edu/~egalcera/papers/projecte_einf_galceran.pdfhaver aconseguit fer petar el software tantes vegades com ha calgut; a la Tali,

282 ValueType value ,

283 ContainerType& container )

284 throw ( std:: runtime_error )

285 {

286 if ( std::find( itemNames_.begin(), itemNames_.end(),

name ) != itemNames_.end() )

287 throw std:: runtime_error( "Name already used:

" + name ) ;

288 itemNames_.push_back( name ) ;

289 container.insert( std:: make_pair( name , value ) ) ;

290 }

291 } ;

292

293 #endif /* CGENERICDATAMANIP_H_ */

113