Skip to content

Commit 5733488

Browse files
author
Olivier Stasse
authored
Merge pull request #53 from jmirabel/master
Add entity Event, Latch, Switch and some operators.
2 parents a1d1a21 + a111a80 commit 5733488

17 files changed

+703
-185
lines changed

include/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ SET(NEWHEADERS
2222
sot/core/matrix-svd.hh
2323
sot/core/contiifstream.hh
2424
sot/core/debug.hh
25+
sot/core/event.hh
2526
sot/core/exception-abstract.hh
2627
sot/core/exception-dynamic.hh
2728
sot/core/exception-factory.hh
@@ -31,7 +32,7 @@ SET(NEWHEADERS
3132
sot/core/exception-tools.hh
3233
sot/core/binary-op.hh
3334
sot/core/derivator.hh
34-
sot/core/switch.hh
35+
sot/core/latch.hh
3536
sot/core/fir-filter.hh
3637
sot/core/integrator-abstract.hh
3738
sot/core/integrator-euler.hh
@@ -86,6 +87,7 @@ SET(NEWHEADERS
8687
sot/core/periodic-call.hh
8788
sot/core/periodic-call-entity.hh
8889
sot/core/trajectory.hh
90+
sot/core/switch.hh
8991
)
9092
INSTALL(FILES ${NEWHEADERS}
9193
DESTINATION include/sot/core

include/sot/core/event.hh

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright (c) 2018, Joseph Mirabel
2+
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
3+
//
4+
// This file is part of sot-core.
5+
// sot-core is free software: you can redistribute it
6+
// and/or modify it under the terms of the GNU Lesser General Public
7+
// License as published by the Free Software Foundation, either version
8+
// 3 of the License, or (at your option) any later version.
9+
//
10+
// sot-core is distributed in the hope that it will be
11+
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12+
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
// General Lesser Public License for more details. You should have
14+
// received a copy of the GNU Lesser General Public License along with
15+
// sot-core. If not, see <http://www.gnu.org/licenses/>.
16+
17+
#ifndef __SOT_EVENT_H__
18+
# define __SOT_EVENT_H__
19+
20+
#include <dynamic-graph/entity.h>
21+
#include <dynamic-graph/signal.h>
22+
#include <dynamic-graph/signal-ptr.h>
23+
#include <dynamic-graph/signal-time-dependent.h>
24+
#include <dynamic-graph/pool.h>
25+
#include <dynamic-graph/command-bind.h>
26+
#include <dynamic-graph/command-getter.h>
27+
28+
#include <sot/core/config.hh>
29+
30+
namespace dynamicgraph {
31+
namespace sot {
32+
/// Event
33+
class SOT_CORE_DLLAPI Event : public dynamicgraph::Entity
34+
{
35+
DYNAMIC_GRAPH_ENTITY_DECL();
36+
37+
Event (const std::string& name) :
38+
Entity (name),
39+
checkSOUT ("Event("+name+")::output(bool)::check"),
40+
conditionSIN(NULL,"Event("+name+")::input(bool)::condition"),
41+
lastVal_ (2) // lastVal_ should be different true and false.
42+
{
43+
checkSOUT.setFunction
44+
(boost::bind (&Event::check, this, _1, _2));
45+
signalRegistration (conditionSIN);
46+
signalRegistration (checkSOUT);
47+
48+
using command::makeCommandVoid1;
49+
std::string docstring =
50+
"\n"
51+
" Add a signal\n";
52+
addCommand ("addSignal", makeCommandVoid1
53+
(*this, &Event::addSignal, docstring));
54+
55+
docstring =
56+
"\n"
57+
" Get list of signals\n";
58+
addCommand ("list", new command::Getter<Event, std::string>
59+
(*this, &Event::getSignalsByName, docstring));
60+
}
61+
62+
~Event () {}
63+
64+
/// Header documentation of the python class
65+
virtual std::string getDocString () const
66+
{
67+
return
68+
"Send an event when the input changes\n\n"
69+
" The signal triggered is called whenever the condition is satisfied.\n";
70+
}
71+
72+
void addSignal (const std::string& signal)
73+
{
74+
std::istringstream iss (signal);
75+
triggers.push_back(&PoolStorage::getInstance()->getSignal (iss));
76+
}
77+
78+
// Returns the Python string representation of the list of signal names.
79+
std::string getSignalsByName () const
80+
{
81+
std::ostringstream oss;
82+
oss << "(";
83+
for (Triggers_t::const_iterator _sig = triggers.begin();
84+
_sig != triggers.end(); ++_sig)
85+
oss << '\'' << (*_sig)->getName() << "\', ";
86+
oss << ")";
87+
return oss.str();
88+
}
89+
90+
private:
91+
typedef SignalBase<int>* Trigger_t;
92+
typedef std::vector<Trigger_t> Triggers_t;
93+
94+
bool& check (bool& ret, const int& time)
95+
{
96+
const bool& val = conditionSIN (time);
97+
ret = (val != lastVal_);
98+
if (ret) {
99+
lastVal_ = val;
100+
for (Triggers_t::const_iterator _s = triggers.begin();
101+
_s != triggers.end(); ++_s)
102+
(*_s)->recompute (time);
103+
}
104+
return ret;
105+
}
106+
107+
Signal <bool, int> checkSOUT;
108+
109+
Triggers_t triggers;
110+
SignalPtr <bool, int> conditionSIN;
111+
112+
bool lastVal_;
113+
};
114+
} // namespace sot
115+
} // namespace dynamicgraph
116+
#endif // __SOT_EVENT_H__

include/sot/core/integrator-abstract.hh

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <dynamic-graph/entity.h>
3434
#include <dynamic-graph/pool.h>
3535
#include <dynamic-graph/all-signals.h>
36+
#include <dynamic-graph/command-bind.h>
3637
#include <sot/core/debug.hh>
3738

3839
/* STD */
@@ -55,11 +56,6 @@ template<class sigT, class coefT>
5556
class IntegratorAbstract
5657
:public dg::Entity
5758
{
58-
public:
59-
virtual const std::string& getClassName() const { return dg::Entity::getClassName(); }
60-
static std::string getTypeName( void ) { return "Unknown"; }
61-
static const std::string CLASS_NAME;
62-
6359
public:
6460
IntegratorAbstract ( const std::string& name )
6561
:dg::Entity(name)
@@ -69,6 +65,29 @@ class IntegratorAbstract
6965
"sotIntegratorAbstract("+name+")::output(vector)::sout")
7066
{
7167
signalRegistration( SIN<<SOUT );
68+
69+
using namespace dg::command;
70+
71+
const std::string typeName =
72+
Value::typeName(dg::command::ValueHelper<coefT>::TypeID);
73+
74+
addCommand ("pushNumCoef",
75+
makeCommandVoid1 (*this, &IntegratorAbstract::pushNumCoef,
76+
docCommandVoid1 ("Push a new numerator coefficient", typeName)
77+
));
78+
addCommand ("pushDenomCoef",
79+
makeCommandVoid1 (*this, &IntegratorAbstract::pushDenomCoef,
80+
docCommandVoid1 ("Push a new denomicator coefficient", typeName)
81+
));
82+
83+
addCommand ("popNumCoef",
84+
makeCommandVoid0 (*this, &IntegratorAbstract::popNumCoef,
85+
docCommandVoid0 ("Pop a new numerator coefficient")
86+
));
87+
addCommand ("popDenomCoef",
88+
makeCommandVoid0 (*this, &IntegratorAbstract::popDenomCoef,
89+
docCommandVoid0 ("Pop a new denomicator coefficient")
90+
));
7291
}
7392

7493
virtual ~IntegratorAbstract() {}

include/sot/core/integrator-euler-impl.hh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@
5757

5858
namespace dynamicgraph {
5959
namespace sot {
60-
DECLARE_SPECIFICATION(IntegratorEulerVectorMatrix,dg::Vector,dg::Matrix)
60+
DECLARE_SPECIFICATION(IntegratorEulerDoubleDouble,double,double)
61+
DECLARE_SPECIFICATION(IntegratorEulerVectorDouble,Vector,double)
62+
DECLARE_SPECIFICATION(IntegratorEulerVectorMatrix,Vector,Matrix)
6163
}
6264
}
6365

include/sot/core/integrator-euler.hh

Lines changed: 80 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
/* SOT */
2929
#include <sot/core/integrator-abstract.hh>
30+
#include <dynamic-graph/command-setter.h>
31+
#include <dynamic-graph/command-getter.h>
3032

3133
/* --------------------------------------------------------------------- */
3234
/* --- CLASS ----------------------------------------------------------- */
@@ -50,7 +52,7 @@ class IntegratorEuler
5052
{
5153

5254
public:
53-
virtual const std::string& getClassName( void ) const { return dg::Entity::getClassName(); }
55+
virtual const std::string& getClassName( void ) const;
5456
static std::string getTypeName( void ) { return "Unknown"; }
5557
static const std::string CLASS_NAME;
5658

@@ -63,8 +65,29 @@ class IntegratorEuler
6365
public:
6466
IntegratorEuler( const std::string& name )
6567
: IntegratorAbstract<sigT,coefT>( name )
68+
, derivativeSOUT(boost::bind(&IntegratorEuler<sigT,coefT>::derivative,this,_1,_2),
69+
SOUT,
70+
"sotIntegratorEuler("+name+")::output(vector)::derivativesout")
6671
{
67-
SOUT.addDependency(SIN);
72+
this->signalRegistration( derivativeSOUT );
73+
74+
using namespace dg::command;
75+
76+
setSamplingPeriod (0.005);
77+
78+
this->addCommand ("setSamplingPeriod",
79+
new Setter<IntegratorEuler,double> (*this,
80+
&IntegratorEuler::setSamplingPeriod,
81+
"Set the time during two sampling."));
82+
this->addCommand ("getSamplingPeriod",
83+
new Getter<IntegratorEuler,double> (*this,
84+
&IntegratorEuler::getSamplingPeriod,
85+
"Get the time during two sampling."));
86+
87+
this->addCommand ("initialize",
88+
makeCommandVoid0 (*this, &IntegratorEuler::initialize,
89+
docCommandVoid0 ("Initialize internal memory from current value of input")
90+
));
6891
}
6992

7093
virtual ~IntegratorEuler( void ) {}
@@ -73,14 +96,16 @@ protected:
7396
std::vector<sigT> inputMemory;
7497
std::vector<sigT> outputMemory;
7598

99+
dg::SignalTimeDependent<sigT, int> derivativeSOUT;
100+
101+
double dt;
102+
double invdt;
103+
76104
public:
77105
sigT& integrate( sigT& res, int time )
78106
{
79107
sotDEBUG(15)<<"# In {"<<std::endl;
80108

81-
const double dt = 0.005;
82-
const double invdt = 200;
83-
84109
sigT sum;
85110
sigT tmp1, tmp2;
86111
const std::vector<coefT>& num = numerator;
@@ -89,33 +114,32 @@ public:
89114
// Step 1
90115
tmp1 = inputMemory[0];
91116
inputMemory[0] = SIN.access(time);
92-
sum.resize(tmp1.size());
93-
sum = denom[0] * inputMemory[0];
117+
sum = num[0] * inputMemory[0];
94118
// End of step 1. Here, sum is b_0 X
95119

96120
// Step 2
97-
int denomsize = denom.size();
98-
for(int i = 1; i < denomsize; ++i)
121+
int numsize = (int)num.size();
122+
for(int i = 1; i < numsize; ++i)
99123
{
100124
tmp2 = inputMemory[i-1] - tmp1;
101125
tmp2 *= invdt;
102126
tmp1 = inputMemory[i];
103127
inputMemory[i] = tmp2;
104-
sum += (denom[i] * inputMemory[i]);
128+
sum += (num[i] * inputMemory[i]);
105129
}
106130
// End of step 2. Here, sum is b_m * d(m)X / dt^m + ... - b_0 X
107131

108132
// Step 3
109-
int numsize = num.size() - 1;
110-
for(int i = 0; i < numsize; ++i)
133+
int denomsize = (int)denom.size() - 1;
134+
for(int i = 0; i < denomsize; ++i)
111135
{
112-
sum -= (num[i] * outputMemory[i]);
136+
sum -= (denom[i] * outputMemory[i]);
113137
}
114138
// End of step 3. Here, sum is b_m * d(m)X / dt^m + ... - b_0 X - a_0 Y - ... a_n-1 d(n-1)Y / dt^(n-1)
115139

116140
// Step 4
117-
outputMemory[numsize] = sum;
118-
for(int i = numsize - 1; i >= 0; --i)
141+
outputMemory[denomsize] = sum;
142+
for(int i = denomsize-1; i >= 0; --i)
119143
{
120144
outputMemory[i] += (outputMemory[i+1] * dt);
121145
}
@@ -127,6 +151,47 @@ public:
127151
sotDEBUG(15)<<"# Out }"<<std::endl;
128152
return res;
129153
}
154+
155+
sigT& derivative ( sigT& res, int time )
156+
{
157+
if (outputMemory.size() < 2)
158+
throw dg::ExceptionSignal (dg::ExceptionSignal::GENERIC,
159+
"Integrator does not compute the derivative.");
160+
161+
SOUT.recompute(time);
162+
res = outputMemory[1];
163+
return res;
164+
}
165+
166+
void setSamplingPeriod (const double& period)
167+
{
168+
dt = period;
169+
invdt = 1/period;
170+
}
171+
172+
double getSamplingPeriod () const
173+
{
174+
return dt;
175+
}
176+
177+
void initialize ()
178+
{
179+
std::size_t numsize = numerator.size();
180+
inputMemory.resize(numsize);
181+
182+
inputMemory[0] = SIN.accessCopy();
183+
for(std::size_t i = 1; i < numsize; ++i)
184+
{
185+
inputMemory[i] = inputMemory[0];
186+
}
187+
188+
std::size_t denomsize = denominator.size();
189+
outputMemory.resize(denomsize);
190+
for(std::size_t i = 0; i < denomsize; ++i)
191+
{
192+
outputMemory[i] = inputMemory[0];
193+
}
194+
}
130195
};
131196

132197
} /* namespace sot */} /* namespace dynamicgraph */

0 commit comments

Comments
 (0)