180 likes | 345 Views
The OpenRDK framework: a not-so-short tutorial Part 2: advanced topics. Daniele Calisi , Andrea Censi. Concurrent access management: locks. Thread 2 …; …; …; …; lock(A); …; a.something(); …; unlock(A); …; …;. Thread 1 …; …; …; lock(a); a.something(); …; …; unlock(a); …;
E N D
The OpenRDK framework:a not-so-short tutorial Part 2: advanced topics Daniele Calisi, Andrea Censi
Concurrent access management: locks Thread 2 …; …; …; …; lock(A); …; a.something(); …; unlock(A); …; …; Thread 1 …; …; …; lock(a); a.something(); …; …; unlock(a); …; …; The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009 In a multithreaded application, all accesses to shared data must be “protected” with a mutex
Concurrent memory access: the session object RAgent Module Module Module Module session session session session Repository The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
Concurrent access management: locks lock() get value unlock() return value double a = session->getDouble(…) session->lock(A) myObject = session->getObject(A) myObject.function1(); myObject.function2(); session->unlock(A) The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009 OpenRDK provides implicit locks/unlocks… …and explicit locks/unlocks (e.g., large objects)
The session object • Similar to DBMS sessions • Recover locked properties • Repository and ModuleManager communication • e.g. session->wait() • URL context (e.g., “/robot/”) • Caching of property names • Starting and ending a session collect statistics (e.g., iteration duration, time between two start, etc.) • Sessions and threads • Mutex (lock/unlock) clean management • One session for each thread (you can create other sessions for your own threads) The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
Module code class TemplateModule { public: TemplateModule(); virtual ~TemplateModule(); bool initConfigurationProperties(); // bool initInterfaceProperties(); bool init(); void exec(); // void exitRequested(); // void cleanup(); // void asyncAgentCmd(cstr cmd); }; The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
initConfigurationProperties() #define PROPERTY_ALPHA “in/alpha” #define PROPERTY_BETA “in/beta” #define PROPERTY_RESULT “out/result” #define PROPERTY_MY_MAP “out/myMap” bool MyModule::initConfigurationProperties() { SESSION_TRY_START(session) // ... session->createDouble(PROPERTY_ALPHA, "Alpha", RDouble::SEC, 10.); session->createDouble(PROPERTY_BETA, "Beta", RDouble::RAD, deg2rad(20.)); session->createDouble(PROPERTY_RESULT, “Result", RDouble::M, 100.); session->createMap(PROPERTY_MY_MAP, “The map", 1., 2., 0., 10., 20, 20); SESSION_END(session) returntrue; SESSION_CATCH_TERMINATE(session) returnfalse; } The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
init() bool MyModule::init() { SESSION_TRY_START(session) // open sockets... // connect to hardware... session->listenToTimer(500.); SESSION_END(session) returntrue; SESSION_CATCH_TERMINATE(session) returnfalse; } The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009 • Can listen to: • timers • property changes • nothing (non-OpenRDK entities: sockets, drivers, ...)
exec() void MyModule::exec() { while (session->wait(), !exiting) { SESSION_TRY_START(session) double alpha = session->getDouble(PROPERTY_ALPHA); double beta = session->getDouble(PROPERTY_BETA); double gamma = alpha * beta; session->setDouble(PROPERTY_RESULT, gamma); session->lock(PROPERTY_MY_MAP, HERE); RMapImage* m = session->getObjectAsL<RMapImage>(PROPERTY_MY_MAP); m->setPixelB(0, 0, RImage::C8Red); session->unlock(PROPERTY_MY_MAP); SESSION_END_CATCH_TERMINATE(session) } } The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
Under the hood: startup order >> Load configuration file << >> Instantiate modules << module1.initConfigurationProperties() module2.initConfigurationProperties() module3.initConfigurationProperties() >> Configure properties (1) << module1.initInterfaceProperties() module2.initInterfaceProperties() module3.initInterfaceProperties() >> Configure properties (2) << module1.init() module2.init() module3.init() module1 module2 module3 The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
Under the hood: execution and termination module1.init() module2.init() module3.init() >> Multithreading starts << module1 module2 module1.exec() module2.exec() module3.exec() module3 module1.exitRequested() module2.exitRequested() module3.exitRequested() >> Multithreading ends << module1.cleanup() module2.cleanup() module3.cleanup() >> Agent terminated << The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
Queues as object dispatchers • Producer/consumer problem; FIFO • Addressed like other properties (URL) • Features • multiple consumers (concurrently) • no object duplication • automatic garbage collection • filters • passive • Can be used for • localization (e.g., laser) • logging Module Queue Queue Queue Module Module The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
The SimpleTcpInterfaceModule • Text-based interaction External application TELNET Example: > propertyList /robot/enabled /robot/odometryPose /localizer/estimatedPose > getValue /robot/enabled Yes > getValue /robot/estimatedPose 10.4 32.12 45° > setValue /robot/enabled No > getValue /robot/enabled No The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
Connection to RT systems RT-Process The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
The build system $ cd TheDirectoryOfMyModules $ rdk-create-module-dir.sh –m MyNewModule $ ls mynewmodule $ ls mynewmodule CMakeLists.txt mynewmodule.h mynewmodule.cpp mynewmodule_names.h $ cd mynewmodule $ cat CMakeLists.txt RDK_ADD_RAGENT_MODULE(ALL_FILES) $ … $ cat CMakeLists.txt IF(PALTALIB_FOUND) RDK_ADD_RAGENT_MODULE(ALL_FILES) INCLUDE_DIRECTORIES(${PALTALIB_INCLUDE_DIR}) LINK_DIRECTORIES(${PALTALIB_LINK_DIRECTORIES}) TARGET_LINK_LIBRARIES(${RDK_THIS_MODULE_NAME} ${PALTALIB_LIBRARIES}) ENDIF(PALTALIB_FOUND) $ The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
OpenRDK current applications • Rescue wheeled robots (real robots, USARSim) • RoboCare project (assistive robots for the elders) • Quadrotor, tarantula (real robots, USARSim) • RoboCup Standard Platform League (“Nao league”) • HRI experiments (robot side) The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
Summary • OpenRDK features • Modularity and concurrent engineering • Full multi-thread support • Blackboard-style communication (properties can be shared among different processes) • Tools (Logging/replaying, RConsole, etc.) • Open source (GPL license) On-going and future work • Extend the property sharing mechanism • More network QoS (e.g., from DDS: latency budget) • On-line fault detection system • Configuration file editing and analysis tools • Graphical on-line configuration editor • Detect possible deadlocks • Verify constraints on schedule • More connectivity with the rest of the world • Scripting (Ruby, Python) support • Design a better logo! The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009
Questions Questions? We are on SourceForge: http://openrdk.sourceforge.net Credits: Prof. Daniele Nardi Developers: Daniele Calisi, Andrea Censi Early contributors: A. Farinelli, G. Grisetti, L. Iocchi Current contributors: F. Giannone, L. Iocchi, M. Leonetti, L. Marchetti, D. Nardi, P. de la Puente, G. Randelli, M. Sbarigia, A. Valero, R. Vicario The OpenRDK framework - tutorial part 2 - OpenRDK Workshop - March 2009