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
35namespace 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 * Streaming operator. Calls the streaming operator of the implementation
175 *
176 * @param stream stream
177 * @param rhs right hand side
178 * @return stream
179 */
180 friend std::ostream&
181 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 using VarList = std::vector<Variant>;
198
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 {
210 public:
211 /**
212 * Construct a literal using a datafieldidentifier as string
213 *
214 * @param dataFieldIdentifierStr dataFieldIdentifier as string
215 * @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
216 * @param checkParameters parameter list for the check
217 */
218 Literal(const std::string& dataFieldIdentifierStr,
219 const std::string& checkName,
220 const VarList& checkParameters = createParameterList());
221
222
223 /**
224 * Construct a literal using a datafieldidentifier object
225 *
226 * @param dataFieldIdentifier dataFieldIdentifier object
227 * @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
228 * @param checkParameters parameter list for the check
229 */
230 Literal(const DataFieldIdentifier& dataFieldIdentifier,
231 const std::string& checkName,
232 const VarList& checkParameters = createParameterList());
233
234 /**
235 * Construct a literal using a datafieldidentifier pointer
236 *
237 * @param dataFieldIdentifier dataFieldIdentifier pointer
238 * @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
239 * @param checkParameters parameter list for the check
240 */
241 Literal(const DataFieldIdentifierPtr& dataFieldIdentifier,
242 const std::string& checkName,
243 const VarList& checkParameters = createParameterList());
244
245 Literal(const DatafieldRefBasePtr& datafieldRef,
246 const std::string& checkName,
247 const VarList& checkParameters = createParameterList());
248
249 /**
250 * Static helper method to create an empty parameterlist
251 *
252 * @return parameterlist as required for the construction of a literal
253 */
255
256 /**
257 * Static helper method to create a parameterlist
258 *
259 * @param param1 first parameter
260 * @return parameterlist as required for the construction of a literal
261 */
262 static VarList createParameterList(const Variant& param1);
263
264 /**
265 * Static helper method to create a parameterlist
266 *
267 * @param param1 first parameter
268 * @param param2 second parameter
269 * @return parameterlist as required for the construction of a literal
270 */
271 static VarList createParameterList(const Variant& param1, const Variant& param2);
272
273 /**
274 * Static helper method to create a parameterlist
275 *
276 * @param param1 first parameter
277 * @param param2 second parameter
278 * @param param3 third parameter
279 * @return parameterlist as required for the construction of a literal
280 */
281 static VarList
282 createParameterList(const Variant& param1, const Variant& param2, const Variant& param3);
283
284 ParameterList toParamList(const VarList& varList) const;
285 };
286} // namespace armarx
std::ostream & operator<<(std::ostream &strm, const AbstractInterface &a)
#define ARMARXCORE_IMPORT_EXPORT
DataFieldIdentifier provide the basis to identify data field within a distributed ArmarX scenario.
Literal(const std::string &dataFieldIdentifierStr, const std::string &checkName, const VarList &checkParameters=createParameterList())
Construct a literal using a datafieldidentifier as string.
Definition Term.cpp:113
ParameterList toParamList(const VarList &varList) const
Definition Term.cpp:180
static VarList createParameterList()
Static helper method to create an empty parameterlist.
Definition Term.cpp:142
Term operator!(void) const
The logical NOT operator.
Definition Term.cpp:80
TermImplPtr getImpl() const
Retrieve term implementation object as used in the ArmarX Framework in order to build distributed exp...
Definition Term.cpp:108
Term()
Construct an empty term.
Definition Term.cpp:30
TermImplPtr termImpl
Definition Term.h:194
Term operator||(const Term &right) const
The logical OR operator.
Definition Term.cpp:67
Term & operator=(const Term &right)
The assignment operator.
Definition Term.cpp:93
Term operator&&(const Term &right) const
The logical AND operator.
Definition Term.cpp:53
The Variant class is described here: Variants.
Definition Variant.h:224
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::vector< Variant > VarList
Definition Term.h:197
IceInternal::Handle< TermImpl > TermImplPtr
Typedef of TermImplPtr as IceInternal::Handle<TermImpl> for convenience.
Definition TermImpl.h:41
IceInternal::Handle< DataFieldIdentifier > DataFieldIdentifierPtr
Typedef of DataFieldIdentifierPtr as IceInternal::Handle<DataFieldIdentifier> for convenience.