Term.h
Go to the documentation of this file.
1 /*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarX::Core
19 * @author Kai Welke (welke _at_ kit _dot_ edu)
20 * @date 2012 Kai Welke
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24 
25 #pragma once
26 
27 // variant includes
30 
31 // condition includes
34 
35 namespace armarx
36 {
37  /**
38  \defgroup Conditions Conditions
39  \ingroup ObserversGrp
40  The ArmarX condition mechanism allows to define a distributed set of condition checks on sensory data and
41  generate events based on the condition checks. These events are used to trigger state transitions in the
42  robot program.
43 
44  The condition mechanism comprises two main elements:
45  - the definition of condition checks on sensory data available in an ArmarX scenario
46  - the definition of boolean expression on top of the condition checks that allow the generation of events in an intuitive manner.
47 
48  \section ConditionChecks Condition checks
49  Condition checks are provided by each observer component in the ArmarX scenario. Condition
50  checks can be instantiated on each datafield provided by the
51  observer. Thereby, datafields are identified by their armarx::DataFieldIdentifier and condition checks
52  are identifier by their name. Further a list of parameters is passed to condition checks.
53 
54  Typical generic condition checks include "equals", "larger", "inrange", "contains" which are already
55  implemented for all applicable datatypes. Further, the condition checks are easily extensible if special checks
56  are needed. See armarx::ConditionCheck for details.
57 
58  \section Expression Definition of conditions
59  Conditions are defined using logical expressions. Each literal in the logical expression represents the state of
60  a distributed condition check. Using logical operations, complex expressions can
61  be achieved. In general, the definition of a condition is very similar to the if-statement:
62  \include Conditions.dox
63 
64  In order to allow a more convenient way for assembling conditions in a loop, an empty term can be defined
65  which is successively defined by adding more literals. Logical operations on empty are not applied, they
66  are replaced by an assignment:
67  \include EmptyTerm.dox
68 
69  \section Implementation Implementation of conditions
70  The implementation of conditions consists of two parts: the user frontend and the framework implementation. A basic
71  overview is shown in this figure, where the user frontend is colored red and the framework implementation blue.
72  \image html condition.png "" witdh=400px
73  \subsection ImplementationFrontend User frontend
74  The user frontend offers a convenient way to define a condition by means of assembling a Term using binary operators &&, || and NOT. The condition is
75  an expression composed of literals as introduced in \ref Expression.
76 
77  Internally, each term builds a TermImpl which is used within the ArmarX framework, to hande the condition checks and to evaluate the term.
78  This implementation is described in the following.
79 
80  \subsection ImplementationFramework Framework implementation
81  The condition is internally represented as binary expression tree. Each node in the tree corresponds to a logical operation such as &&, || and NOT.
82  The leaves of the expression tree correspond to literals, which are associated with condition checks (see \ref ConditionChecks).
83 
84  Each node of the tree inherits from the TermImpl superclass, which stores the linkage in the tree and a boolean value which encodes the current
85  state of the node. Further, an update method is provided, which takes the value from the children of the node and performes the operation specific
86  to the node in order to update its state. Once the value has been updated, the update of the parent node is called.
87 
88  Concrete implementations of TermImpl are provided by subclassing the TermImpl. Three different subclasses are implemented: the LiteralImpl, the Operation, and
89  the ConditionRoot. The LiteralImpl correspond to condition checks and are updated by evaluation atomar checks on datafields. The value of a LiteralImpl
90  corresponds to the result of the condition check. On top of the LiteralImpl, a set of operations can be defined using the Operation subclass. The available
91  operations correspond to the logical operations &&, || and NOT provided by the user frontend. Finally, the top node of the tree is realized by the
92  class ConditionRoot, which fires an event, once the expression represented by the tree is fulfilled.
93 
94  The following image illustrates a complete expression tree as build by the ArmarX framework:
95  \image html ExpressionTree.png "" witdh=300px
96 
97  The expression tree corresponds to the example code given in section \ref Expression. The trees can be visualized including their state and associated checks
98  with the ConditionViewerWidget from the ArmarX Gui.
99 
100  * @class Term
101  * @ingroup Conditions
102  *
103  * Terms are part of the user front end of the ArmarX condition mechanism.
104  * Terms describe boolean expressions of condition checks. The logical operations AND, OR and
105  * NOT are implemented for terms. Terms are composed of several Literals
106  * which correspond to condition checks.
107  *
108  * \see Conditions
109  * \see Literal
110  */
112  {
113  public:
114  /**
115  * Construct an empty term. For empty terms, the first operations is interpreted as
116  * assignment.
117  * An empty term is always evaluated to 'true'.
118  */
119  Term();
120 
121  /**
122  * Copy constructor.
123  *
124  * @param other to copy
125  */
126  Term(const Term& other);
127 
128  /**
129  * Construct term by term implementation
130  *
131  * @param implementation (will not be copied)
132  */
133  Term(TermImplPtr impl);
134 
135  /**
136  * The logical AND operator
137  *
138  * @param another term or literal
139  * @return the resulting expression
140  */
141  Term operator&&(const Term& right) const;
142 
143  /**
144  * The logical OR operator
145  *
146  * @param another term or literal
147  * @return the resulting expression
148  */
149  Term operator||(const Term& right) const;
150 
151  /**
152  * The logical NOT operator
153  *
154  * @return the resulting expression
155  */
156  Term operator!(void) const;
157 
158  /**
159  * The assignment operator
160  *
161  * @param another term or literal
162  * @return the term
163  */
164  Term& operator=(const Term& right);
165 
166  /**
167  * Retrieve term implementation object as used in the ArmarX Framework in order to build distributed expression trees.
168  *
169  * @return the term implementation
170  */
171  TermImplPtr getImpl() const;
172 
173 
174  /**
175  * Streaming operator. Calls the streaming operator of the implementation
176  *
177  * @param stream stream
178  * @param rhs right hand side
179  * @return stream
180  */
181  friend std::ostream& operator<<(std::ostream& stream, const Term& rhs)
182  {
183  // call streaming operator on implementation
184  if (rhs.termImpl)
185  {
186  stream << rhs.termImpl;
187  }
188 
189  return stream;
190  }
191 
192  protected:
193  // reference to term implementation
195  };
196 
197 
198  using VarList = std::vector<Variant>;
199  /**
200  * @class Literal
201  * @ingroup Conditions
202  *
203  * Literals are part of the user front end of the ArmarX condition mechanism.
204  * Literals describe condition checks in the distributed ArmarX scenario.
205  *
206  * \see Conditions
207  */
209  public Term
210  {
211  public:
212  /**
213  * Construct a literal using a datafieldidentifier as string
214  *
215  * @param dataFieldIdentifierStr dataFieldIdentifier as string
216  * @param checkName name of the check as available in the observer. The usual checks can be found in the namespace ::armarx::checks. For the available checks for the specific observer, check the Gui ObserverView while the Observer is running
217  * @param checkParameters parameter list for the check
218  */
219  Literal(const std::string& dataFieldIdentifierStr, const std::string& checkName, const VarList& checkParameters = createParameterList());
220 
221 
222  /**
223  * Construct a literal using a datafieldidentifier object
224  *
225  * @param dataFieldIdentifier dataFieldIdentifier object
226  * @param checkName name of the check as available in the observer. The usual checks can be found in the namespace ::armarx::checks. For the available checks for the specific observer, check the Gui ObserverView while the Observer is running
227  * @param checkParameters parameter list for the check
228  */
229  Literal(const DataFieldIdentifier& dataFieldIdentifier, const std::string& checkName, const VarList& checkParameters = createParameterList());
230 
231  /**
232  * Construct a literal using a datafieldidentifier pointer
233  *
234  * @param dataFieldIdentifier dataFieldIdentifier pointer
235  * @param checkName name of the check as available in the observer. The usual checks can be found in the namespace ::armarx::checks. For the available checks for the specific observer, check the Gui ObserverView while the Observer is running
236  * @param checkParameters parameter list for the check
237  */
238  Literal(const DataFieldIdentifierPtr& dataFieldIdentifier, const std::string& checkName, const VarList& checkParameters = createParameterList());
239 
240  Literal(const DatafieldRefBasePtr& datafieldRef, const std::string& checkName, const VarList& checkParameters = createParameterList());
241 
242  /**
243  * Static helper method to create an empty parameterlist
244  *
245  * @return parameterlist as required for the construction of a literal
246  */
247  static VarList createParameterList();
248 
249  /**
250  * Static helper method to create a parameterlist
251  *
252  * @param param1 first parameter
253  * @return parameterlist as required for the construction of a literal
254  */
255  static VarList createParameterList(const Variant& param1);
256 
257  /**
258  * Static helper method to create a parameterlist
259  *
260  * @param param1 first parameter
261  * @param param2 second parameter
262  * @return parameterlist as required for the construction of a literal
263  */
264  static VarList createParameterList(const Variant& param1, const Variant& param2);
265 
266  /**
267  * Static helper method to create a parameterlist
268  *
269  * @param param1 first parameter
270  * @param param2 second parameter
271  * @param param3 third parameter
272  * @return parameterlist as required for the construction of a literal
273  */
274  static VarList createParameterList(const Variant& param1, const Variant& param2, const Variant& param3);
275 
276  ParameterList toParamList(const VarList& varList) const;
277  };
278 }
279 
LiteralImpl.h
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
DataFieldIdentifier.h
TermImpl.h
armarx::Term
Definition: Term.h:111
armarx::VarList
std::vector< Variant > VarList
Definition: Term.h:198
armarx::Term::operator<<
friend std::ostream & operator<<(std::ostream &stream, const Term &rhs)
Streaming operator.
Definition: Term.h:181
IceInternal::Handle< TermImpl >
armarx::Term::termImpl
TermImplPtr termImpl
Definition: Term.h:194
armarx::Literal
Definition: Term.h:208
ARMARXCORE_IMPORT_EXPORT
#define ARMARXCORE_IMPORT_EXPORT
Definition: ImportExport.h:38
Variant.h
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::DataFieldIdentifier
DataFieldIdentifier provide the basis to identify data field within a distributed ArmarX scenario.
Definition: DataFieldIdentifier.h:48