Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
doc:logging:tutorials-cpp [2014/09/04 15:39] – winkler | doc:logging:tutorials-cpp [2014/09/19 15:19] (current) – [Non-Default Contexts] winkler | ||
---|---|---|---|
Line 1: | Line 1: | ||
===== Tutorial for the C++ Beliefstate Client Library ===== | ===== 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 ==== | ==== What it can do ==== | ||
The Beliefstate Client library allows easy, lightweight access to the | The Beliefstate Client library allows easy, lightweight access to the | ||
- | Beliefstate | + | Beliefstate |
consist of opening a new semantic context in which actions take place, | consist of opening a new semantic context in which actions take place, | ||
and ending that context again, annotating it with success or | and ending that context again, annotating it with success or | ||
Line 33: | Line 36: | ||
wstool set beliefstate_client --git https:// | wstool set beliefstate_client --git https:// | ||
- | After doing a wstool update to make sure all library checkouts are up | + | After doing a '' |
to date, make sure that everything compiles just fine: | to date, make sure that everything compiles just fine: | ||
Line 51: | Line 54: | ||
The package' | The package' | ||
- | (roscpp) and the Beliefstate Client library (beliefstate_client). | + | ('' |
- | This package' | + | This package' |
including: | including: | ||
Line 59: | Line 62: | ||
#include < | #include < | ||
#include < | #include < | ||
- | #include < | + | #include < |
+ | #include <beliefstate_client/Context.h> | ||
+ | |||
+ | using namespace beliefstate_client; | ||
int main(int argc, char** argv) { | int main(int argc, char** argv) { | ||
Line 95: | Line 102: | ||
| | ||
// Open a top-level context (level 0) | // Open a top-level context (level 0) | ||
- | | + | |
| | ||
// Open a sub-context (level 1) | // Open a sub-context (level 1) | ||
- | | + | |
- | // End the sub-context from level 1 | + | |
- | bscl-> | + | |
- | | + | |
// Open another sub-context (level 1) | // Open another sub-context (level 1) | ||
- | | + | |
- | + | ||
- | // Open yet another sub-context (level 2) | + | // Close the first sub-context |
- | int nContextID_3 = bscl-> | + | |
- | // End the sub-context | + | |
- | | + | |
| | ||
- | // End the sub-context | + | // Close the second |
- | | + | |
| | ||
// End the top-level context | // End the top-level context | ||
- | | + | |
| | ||
// Actual logging ends here. | // Actual logging ends here. | ||
Line 120: | Line 123: | ||
The logging result of this program is a nested tree with two branches | The logging result of this program is a nested tree with two branches | ||
- | from the top-level node, one with depth 1, and one with depth 2. | + | 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 | To export the logged tree now, we add another call from inside the | ||
Line 135: | Line 140: | ||
The Beliefstate system (if properly configured with exporter plugins) | The Beliefstate system (if properly configured with exporter plugins) | ||
- | now exports a .owl-file, including well-structured OWL code describing | + | now exports a '' |
- | the tree semantics, and a .dot-file, in graphviz format for PDF | + | the tree semantics, and a '' |
generation. | generation. | ||
+ | A resulting PDF could then look like this: | ||
+ | {{ : | ||
==== Non-Default Contexts ==== | ==== Non-Default Contexts ==== | ||
- | To override default-parameters, | + | To override default-parameters, |
- | * The start and end timestamps for the context timepoints | + | * the start and end timestamps for the context timepoints, and |
- | * The result success flag for ending contexts | + | * the result success flag for ending contexts |
- | The signature of the startContext call looks like this: | + | The signature of the '' |
<code pseudo> | <code pseudo> | ||
- | int startContext(context-name, | + | Context* Context::startContext(context-name, |
</ | </ | ||
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. | 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 endContext | + | The same accounts for the '' |
<code pseudo> | <code pseudo> | ||
- | int endContext(context-name, | + | void Context:: |
</ | </ | ||
- | The success flag is by default true. For the end timestamp, the same rules apply as for the start timestamp. | + | The success flag is by default |
+ | |||
+ | |||
+ | === 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 | ||
+ | '' | ||
+ | where the shortcut is the short version of the namespace, i.e. '' | ||
+ | ==== Sample Program ==== | ||
+ | |||
+ | A complete sample program depicting the '' |