GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/catkin/dg_control/dynamic_graph_manager/src/periodic-call.cpp Lines: 52 111 46.8 %
Date: 2020-04-15 11:50:02 Branches: 77 258 29.8 %

Line Branch Exec Source
1
/**
2
 * @file periodic-call.cpp
3
 * @author Maximilien Naveau (maximilien.naveau@gmail.com)
4
 * @license License BSD-3-Clause
5
 * @copyright Copyright (c) 2019, New York University and Max Planck Gesellschaft.
6
 * @date 2019-05-22
7
 */
8
9
#include <algorithm>
10
#include <dynamic-graph/pool.h>
11
#include <dynamic-graph/python/interpreter.hh>
12
#include <dynamic-graph/all-commands.h>
13
#include <dynamic-graph/exception-factory.h>
14
#include <dynamic-graph/debug.h>
15
16
#include <dynamic_graph_manager/exception/exception-tools.hh>
17
#include <dynamic_graph_manager/periodic-call.hh>
18
19
using namespace std;
20
using namespace dynamic_graph;
21
namespace dg = dynamicgraph;
22
23
40
PeriodicCall::PeriodicCall( void ):
24
  signal_map_(),
25
  cmd_list_(),
26
  inner_time_( 0 ),
27
40
  py_interpreter_( nullptr )
28
{
29
40
}
30
31
9
void PeriodicCall::addSignal( const std::string &name,
32
                              dg::SignalBase<int>& sig )
33
{
34
9
  signal_map_[ name ] = SignalToCall(&sig);
35
9
  return ;
36
}
37
38
9
void PeriodicCall::addSignal( const std::string& sigpath )
39
{
40
18
  std::istringstream sig_iss( sigpath );
41
  dg::SignalBase<int>& signal =
42

9
      ::dg::PoolStorage::getInstance()->getSignal( sig_iss );
43
9
  addSignal( sigpath,signal );
44
18
  return ;
45
}
46
47
2
void PeriodicCall::addDownsampledSignal(
48
    const std::string &name,
49
    dg::SignalBase<int>& sig,
50
    const unsigned int& downsamplingFactor )
51
{
52
2
  signal_map_[ name ] = SignalToCall(&sig,downsamplingFactor);
53
2
  return ;
54
}
55
56
2
void PeriodicCall::addDownsampledSignal(
57
    const std::string& sigpath,
58
    const unsigned int& downsamplingFactor )
59
{
60
4
  std::istringstream sig_iss( sigpath );
61
  dg::SignalBase<int>& signal =
62

2
      ::dg::PoolStorage::getInstance()->getSignal( sig_iss );
63
2
  addDownsampledSignal( sigpath,signal,downsamplingFactor );
64
4
  return ;
65
}
66
67
void PeriodicCall::
68
rmSignal( const std::string &name )
69
{
70
  signal_map_.erase( name );
71
  return ;
72
}
73
74
void PeriodicCall::
75
addCmd( const std::string& cmdLine )
76
{
77
  cmd_list_.push_back( cmdLine );
78
  return ;
79
}
80
81
void PeriodicCall::
82
rmCmd( const std::string& args )
83
{
84
  CmdListType::iterator iter = std::find( cmd_list_.begin(),cmd_list_.end(),args);
85
  if( cmd_list_.end()!=iter ) {
86
    cmd_list_.erase( iter );
87
  }
88
}
89
90
4
void PeriodicCall::
91
runSignals( const int& t )
92
{
93
18
  for( SignalMapType::iterator iter = signal_map_.begin();
94
12
       signal_map_.end()!=iter; ++iter )
95
  {
96
2
    if( static_cast<unsigned int>(t) % iter->second.down_sampling_factor_ == 0)
97
    {
98
2
      (*iter).second.signal_->recompute( t );
99
    }
100
  }
101
4
  return ;
102
}
103
104
4
void PeriodicCall::
105
runCmds( void )
106
{
107
4
  if( nullptr == py_interpreter_ )
108
  {
109
    ExceptionTools( ExceptionTools::PY_SHELL_PTR,
110

4
                    "Python interpreter not set." );
111
  }
112
113
8
  std::string result, out, err;
114
115
12
  for( CmdListType::const_iterator iter = cmd_list_.begin();
116
8
       cmd_list_.end()!=iter; ++iter )
117
  {
118
    py_interpreter_->python( *iter, result, out, err );
119
  }
120
8
  return ;
121
}
122
123
4
void PeriodicCall::
124
run( const int & t )
125
{
126
4
  runSignals( t ); runCmds();
127
4
  return ;
128
}
129
130
/* --------------------------------------------------------------------- */
131
/* --------------------------------------------------------------------- */
132
/* --------------------------------------------------------------------- */
133
134
135
void PeriodicCall::
136
display( std::ostream& os ) const
137
{
138
  os <<"  (t=" << inner_time_ << ")" <<endl;
139
140
  os<<" -> SIGNALS:"<<endl;
141
  for( SignalMapType::const_iterator iter = signal_map_.begin();
142
       signal_map_.end()!=iter; ++iter )
143
  {
144
    os << " - " << (*iter).first << endl;
145
  }
146
147
  os<<" -> CMDS:"<<endl;
148
  for( CmdListType::const_iterator iter = cmd_list_.begin();
149
       cmd_list_.end()!=iter; ++iter )
150
  {
151
    os << " - " <<  (*iter) << endl;
152
  }
153
154
}
155
156
static std::string readLineStr( istringstream& args )
157
{
158
  stringbuf* pbuf=args.rdbuf();
159
  const std::streamsize size = pbuf->in_avail();
160
  char * buffer = new char[ size+1 ];
161
  pbuf->sgetn( buffer,size );
162
163
  buffer[size]='\0';
164
  std::string res( buffer );
165
  delete [] buffer;
166
  return res;
167
}
168
169
bool PeriodicCall::
170
commandLine( const std::string& cmdLine,
171
             std::istringstream& cmdArgs,
172
             std::ostream& os )
173
{
174
  if( cmdLine == "help" )
175
  {
176
    os << "PeriodicCall:"<<endl
177
       <<"  - addSignal/rmSignal  <int> " <<endl
178
      <<"  - addCmd/rmCmd  " <<endl
179
     <<"  - runSignal/runCmd " <<endl
180
    <<"  - run" <<endl;
181
  }
182
  else if( cmdLine == "addSignal" )
183
  {
184
    std::string sigpath; cmdArgs >> std::skipws >> sigpath;
185
    addSignal( sigpath );
186
  }
187
  else if( cmdLine == "rmSignal" )
188
  {
189
    std::string sigpath; cmdArgs >> std::skipws >> sigpath;
190
    rmSignal( sigpath );
191
  }
192
  else if( cmdLine == "runSignals" )
193
  {      runSignals( inner_time_++ );    }
194
195
  else if( cmdLine == "addCmd" )
196
  {      addCmd( readLineStr(cmdArgs) );    }
197
  else if( cmdLine == "rmCmd" )
198
  {      rmCmd( readLineStr(cmdArgs) );    }
199
  else if( cmdLine == "runCmds" )
200
  {      runCmds();    }
201
202
  else if( cmdLine == "run" )
203
  {      run( inner_time_++ );    }
204
  else if( cmdLine == "clear" )
205
  {     clear();    }
206
  else if( cmdLine == "print" )
207
  { display(os) ; }
208
  else { return false; }
209
  return true;
210
}
211
212
#define ADD_COMMAND( name,def )                                     \
213
  if (commandMap.count(prefix+name) != 0) {                            \
214
  DG_THROW dg::ExceptionFactory(dg::ExceptionFactory::OBJECT_CONFLICT,        \
215
  "Command " + prefix+name +	               \
216
  " already registered in Entity.");          \
217
  }                                                                       \
218
  commandMap.insert( std::make_pair( prefix+name,def ) )
219
220
221
40
void PeriodicCall::addSpecificCommands(dg::Entity& ent,
222
                                       dg::Entity::CommandMap_t& commandMap,
223
                                       const std::string& prefix )
224
{
225
  using namespace dg::command;
226
227
  /* Explicit typage to help the compiler. */
228
  boost::function< void( const std::string& ) >
229

80
      addSignal  = boost::bind( &PeriodicCall::addSignal, this,_1 ),
230

80
      rmSignal = boost::bind( &PeriodicCall::rmSignal, this,_1 );
231
  boost::function< void( const std::string&, const unsigned int& ) >
232

80
      addDownsampledSignal  = boost::bind( &PeriodicCall::addDownsampledSignal, this,_1,_2);
233
  boost::function< void( void ) >
234

80
      clear  = boost::bind( &PeriodicCall::clear, this );
235
  boost::function< void( std::ostream& ) >
236

80
      disp  = boost::bind( &PeriodicCall::display, this,_1 );
237
238






80
  ADD_COMMAND("addSignal",
239
              makeCommandVoid1(ent,addSignal,
240
                               docCommandVoid1("Add the signal to the refresh list",
241
40
                                               "string (sig name)")));
242







80
  ADD_COMMAND("addDownsampledSignal",
243
              makeCommandVoid2(ent,addDownsampledSignal,
244
                               docCommandVoid2("Add the signal to the refresh list",
245
                                               "string (sig name)",
246
40
                                               "unsigned int (downsampling factor, 1 means every time, 2 means every other time, etc...")));
247






80
  ADD_COMMAND("rmSignal",
248
              makeCommandVoid1(ent,rmSignal,
249
                               docCommandVoid1("Remove the signal to the refresh list",
250
40
                                               "string (sig name)")));
251






80
  ADD_COMMAND("clear",
252
              makeCommandVoid0(ent,clear,
253
40
                               docCommandVoid0("Clear all signals and commands from the refresh list.")));
254
255






80
  ADD_COMMAND("disp",
256
              makeCommandVerbose(ent,disp,
257
40
                                 docCommandVerbose("Print the list of to-refresh signals and commands.")));
258
259

52
}
260
261
262
/*
263
 * Local variables:
264
 * c-basic-offset: 2
265
 * End:
266
 */
267