no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
Previous revisionLast revision | |||
— | doc:logging:tutorials-cpp [2014/09/19 15:15] – [Non-Default Contexts] winkler | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ===== Tutorial for the C++ Beliefstate Client Library ===== | ||
+ | Please keep in mind that you need the Beliefstate system running in order to let your program interact with it. | ||
+ | |||
+ | |||
+ | ==== What it can do ==== | ||
+ | |||
+ | The Beliefstate Client library allows easy, lightweight access to the | ||
+ | Beliefstate infrastructure for semantic event logging. Its main tasks | ||
+ | consist of opening a new semantic context in which actions take place, | ||
+ | and ending that context again, annotating it with success or | ||
+ | failure. Such contexts can be nested at will. | ||
+ | |||
+ | Besides recording such events from a live running system (such as a | ||
+ | robotic agent performing tasks in the real world, or a simulated | ||
+ | machine working out given tasks), the recorded events can be exported | ||
+ | as well-structured OWL files, allowing symbolic reasoning about the | ||
+ | available information. | ||
+ | |||
+ | |||
+ | ==== What is needed ==== | ||
+ | |||
+ | In order to equip a program with logging functionality, | ||
+ | linked against the client library. The library is currently only | ||
+ | available in C++, but the functionality is available to all | ||
+ | programming languages that have access to the ROS messaging (and | ||
+ | service) bus. | ||
+ | |||
+ | To get the necessary libraries, you must check out the following | ||
+ | repositories into your catkin ROS workspace: | ||
+ | |||
+ | wstool set designator_integration --git https:// | ||
+ | |||
+ | wstool set iai_common_msgs --git https:// | ||
+ | |||
+ | wstool set beliefstate_client --git https:// | ||
+ | |||
+ | After doing a '' | ||
+ | to date, make sure that everything compiles just fine: | ||
+ | |||
+ | catkin_make --pkg beliefstate_client | ||
+ | |||
+ | If no problems come up, you are set to connect your own applications | ||
+ | to the logging infrastructure. | ||
+ | |||
+ | |||
+ | ==== Using the client library ==== | ||
+ | |||
+ | To clarify how to implement a logging infrastructure interface into | ||
+ | your own ROS application, | ||
+ | first create this node's package by running: | ||
+ | |||
+ | catkin_create_pkg logging_node_client roscpp beliefstate_client | ||
+ | |||
+ | The package' | ||
+ | ('' | ||
+ | |||
+ | This package' | ||
+ | including: | ||
+ | |||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | using namespace beliefstate_client; | ||
+ | |||
+ | |||
+ | int main(int argc, char** argv) { | ||
+ | ros:: | ||
+ | | ||
+ | // Begin main code here. | ||
+ | // ... | ||
+ | // Main code ends here. | ||
+ | | ||
+ | return EXIT_SUCCESS; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | We now add an instance of the Beliefstate Client class that takes | ||
+ | advantage of the already present ROS connection: | ||
+ | |||
+ | <code cpp> | ||
+ | // Begin main code here. | ||
+ | | ||
+ | BeliefstateClient* bscl = new BeliefstateClient(" | ||
+ | | ||
+ | // Begin actual logging here. | ||
+ | // ... | ||
+ | // Actual logging ends here. | ||
+ | | ||
+ | delete bscl; | ||
+ | | ||
+ | // Main code ends here. | ||
+ | </ | ||
+ | |||
+ | To log semantic events, we create some sample nested contexts: | ||
+ | |||
+ | <code cpp> | ||
+ | // Begin actual logging here. | ||
+ | | ||
+ | // Open a top-level context (level 0) | ||
+ | Context* ctxMain = new Context(bscl, | ||
+ | | ||
+ | // Open a sub-context (level 1) | ||
+ | Context* ctxCupOnTable = ctxMain-> | ||
+ | |||
+ | // Open another sub-context (level 1) | ||
+ | Context* ctxCupInRoom = ctxMain-> | ||
+ | |||
+ | // Close the first sub-context | ||
+ | ctxCupOnTable-> | ||
+ | | ||
+ | // Close the second sub-context | ||
+ | ctxCupInRoom-> | ||
+ | | ||
+ | // End the top-level context | ||
+ | ctxMain-> | ||
+ | | ||
+ | // Actual logging ends here. | ||
+ | </ | ||
+ | |||
+ | The logging result of this program is a nested tree with two branches | ||
+ | from the top-level node. The logged circumstances here could be that a cup that formerly sat on a table in a room was first removed from the table (ending the '' | ||
+ | |||
+ | Contexts can be hierarchically nested, or can be concatenated concurrently. A good practice is to always have one main context from which all other contexts derive. Don't create multiple contexts using '' | ||
+ | |||
+ | To export the logged tree now, we add another call from inside the | ||
+ | library: | ||
+ | |||
+ | <code cpp> | ||
+ | // ... | ||
+ | | ||
+ | // Export files | ||
+ | bscl-> | ||
+ | | ||
+ | // Actual logging ends here. | ||
+ | </ | ||
+ | |||
+ | The Beliefstate system (if properly configured with exporter plugins) | ||
+ | now exports a '' | ||
+ | the tree semantics, and a '' | ||
+ | generation. | ||
+ | |||
+ | A resulting PDF could then look like this: | ||
+ | {{ : | ||
+ | ==== Non-Default Contexts ==== | ||
+ | |||
+ | To override default-parameters, | ||
+ | |||
+ | * the start and end timestamps for the context timepoints, and | ||
+ | * the result success flag for ending contexts | ||
+ | |||
+ | The signature of the '' | ||
+ | |||
+ | <code pseudo> | ||
+ | Context* Context:: | ||
+ | </ | ||
+ | So the time point noted in the resulting log-tree can be annotated with a custom timepoint (for non-realtime logging uses). If this parameter is omitted, the current Unix time on the system running the Beliefstate logging system is used. | ||
+ | |||
+ | The same accounts for the '' | ||
+ | <code pseudo> | ||
+ | void Context:: | ||
+ | </ | ||
+ | The success flag is by default set to '' | ||
+ | |||
+ | |||
+ | === Changing the OWL Class and Individual Name in the Resulting OWL File === | ||
+ | |||
+ | To change the '' | ||
+ | |||
+ | <code pseudo> | ||
+ | Context* Context:: | ||
+ | </ | ||
+ | |||
+ | So in order to produce OWL output like this: | ||
+ | <code xml> | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | In you C++-program, | ||
+ | <code cpp> | ||
+ | Context* ctxContext = ctxMain-> | ||
+ | ctxContext-> | ||
+ | </ | ||
+ | |||
+ | Of course, for real-time purposes (or if you don't care about the timestamps), | ||
+ | |||
+ | |||
+ | === Issueing Discrete Events === | ||
+ | |||
+ | When your application requires the issuance of discrete, momentarily events you can use the convenience function '' | ||
+ | <code pseudo> | ||
+ | void Context:: | ||
+ | </ | ||
+ | |||
+ | This implicitly starts a context with the given information, | ||
+ | |||
+ | |||
+ | === Annotating Custom Parameters === | ||
+ | |||
+ | To add custom information to individual task contexts, parameters can be manually annotated to each context. Let's assume, the information | ||
+ | < | ||
+ | X = 5 | ||
+ | Room = Kitchen | ||
+ | </ | ||
+ | should be added to the current context. To achieve this, in your program, call these lines while you are in the appropriate context: | ||
+ | <code cpp> | ||
+ | ctxContext-> | ||
+ | ctxContext-> | ||
+ | </ | ||
+ | The resulting '' | ||
+ | <code xml> | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | The lines | ||
+ | <code xml> | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | now explicitly denote the given parameter values, while | ||
+ | <code xml> | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | Describe the parameter names that were manually annotated. So looking for all properties of type '' | ||
+ | <code xml> | ||
+ | < | ||
+ | </ | ||
+ | is a reference to the designator published via the ROS topic ''/ | ||
+ | |||
+ | |||
+ | === Adding Object References === | ||
+ | In some situations, it is useful to manually annotate objects that are part of the current scene, and maybe play a significant role for the current task. Object references to the currently active task can be annotated in a convenient way, producing output like this: | ||
+ | <code xml> | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | This is achieved by using the following, simple code: | ||
+ | <code cpp> | ||
+ | Context* ctxInCtct = ctxMain-> | ||
+ | |||
+ | Object* objCup = new Object("& | ||
+ | ctxInCtct-> | ||
+ | |||
+ | Object* objTable = new Object("& | ||
+ | ctxInCtct-> | ||
+ | |||
+ | delete objCup; | ||
+ | delete objTable; | ||
+ | |||
+ | ctxInCtct-> | ||
+ | </ | ||
+ | Additionally, | ||
+ | <code xml> | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | The '' | ||
+ | <code pseudo> | ||
+ | new Object(string object-class-namespace, | ||
+ | </ | ||
+ | If they are left out, the object will be of type ''& | ||
+ | <code pseudo> | ||
+ | void Context:: | ||
+ | </ | ||
+ | produces the actual addition of the object reference to the current context (and creation of the object individual). The optional '' | ||
+ | |||
+ | |||
+ | === Registering custom OWL namespaces === | ||
+ | |||
+ | When using custom namespaces in the entity class definitions, | ||
+ | <code cpp> | ||
+ | bscl-> | ||
+ | </ | ||
+ | with both parameters representing your use-case, of course. | ||
+ | |||
+ | Custom namespaces can therefore be registered by calling | ||
+ | `void BeliefstateClient:: | ||
+ | where the shortcut is the short version of the namespace, i.e. `sim`, and the IRI is the actual URL you want to have associated. | ||
+ | ==== Sample Program ==== | ||
+ | |||
+ | A complete sample program depicting the '' |