GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
// |
||
2 |
// Copyright (C) 2012, 2013, 2017 LAAS-CNRS |
||
3 |
// |
||
4 |
// From Author: Florent Lamiraux, Mehdi Benallegue, |
||
5 |
// Author: Olivier Stasse, Rohan Budhiraja |
||
6 |
// Simple sequence player just playing back a set of poses. |
||
7 |
// |
||
8 |
|||
9 |
#include "sot/tools/simpleseqplay.hh" |
||
10 |
|||
11 |
#include <dynamic-graph/command-bind.h> |
||
12 |
#include <dynamic-graph/command-direct-getter.h> |
||
13 |
#include <dynamic-graph/command-direct-setter.h> |
||
14 |
#include <dynamic-graph/command-setter.h> |
||
15 |
|||
16 |
#include <boost/tokenizer.hpp> |
||
17 |
#include <iostream> |
||
18 |
#include <stdexcept> |
||
19 |
#include <vector> |
||
20 |
|||
21 |
namespace dynamicgraph { |
||
22 |
namespace sot { |
||
23 |
using command::docDirectGetter; |
||
24 |
using command::docDirectSetter; |
||
25 |
using command::makeDirectGetter; |
||
26 |
using command::makeDirectSetter; |
||
27 |
|||
28 |
namespace tools { |
||
29 |
using dynamicgraph::Entity; |
||
30 |
using dynamicgraph::command::docCommandVoid0; |
||
31 |
using dynamicgraph::command::docCommandVoid1; |
||
32 |
using dynamicgraph::command::makeCommandVoid0; |
||
33 |
using dynamicgraph::command::makeCommandVoid1; |
||
34 |
|||
35 |
1 |
SimpleSeqPlay::SimpleSeqPlay(const std::string& name) |
|
36 |
: Entity(name), |
||
37 |
firstSINTERN(NULL, sotNOSIGNAL, |
||
38 |
✓✗ | 2 |
"SimpleSeqPlay(" + name + ")::intern(dummy)::init"), |
39 |
postureSOUT_(boost::bind(&SimpleSeqPlay::computePosture, this, _1, _2), |
||
40 |
currentPostureSIN_, |
||
41 |
✓✗ | 2 |
"SimpleSeqPlay(" + name + ")::output(vector)::posture"), |
42 |
currentPostureSIN_( |
||
43 |
✓✗ | 2 |
NULL, "SimpleSeqPlay(" + name + ")::input(vector)::currentPosture"), |
44 |
state_(0), |
||
45 |
startTime_(0), |
||
46 |
posture_(), |
||
47 |
time_(0), |
||
48 |
dt_(0.001), |
||
49 |
time_to_start_(3.0), |
||
50 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
7 |
it_nbs_in_state1_(0) { |
51 |
✓✗ | 1 |
firstSINTERN.setConstant(0); |
52 |
✓✗✓✗ |
1 |
signalRegistration(postureSOUT_); |
53 |
✓✗✓✗ |
1 |
signalRegistration(currentPostureSIN_); |
54 |
|||
55 |
std::string docstring = |
||
56 |
"Load files describing a whole-body motion as reference feature " |
||
57 |
"trajectories\n" |
||
58 |
"\n" |
||
59 |
" Input:\n" |
||
60 |
" - string filename without extension\n" |
||
61 |
"\n" |
||
62 |
" Data is read from the following files:\n" |
||
63 |
" - posture from file \"filename.posture\",\n" |
||
64 |
" The file should contain one column for time and as many columns as" |
||
65 |
" required\n" |
||
66 |
" depending of degree-of-freedrom.\n" |
||
67 |
✓✗ | 1 |
"\n"; |
68 |
✓✗✓✗ ✓✗ |
1 |
addCommand("load", makeCommandVoid1(*this, &SimpleSeqPlay::load, docstring)); |
69 |
|||
70 |
✓✗✓✗ ✓✗ |
1 |
addCommand("start", makeCommandVoid0(*this, &SimpleSeqPlay::start, |
71 |
✓✗✓✗ |
2 |
docCommandVoid0("Start motion"))); |
72 |
|||
73 |
docstring = |
||
74 |
"Set the time between the robot current pose and the starting of the " |
||
75 |
✓✗ | 1 |
"buffer \n"; |
76 |
|||
77 |
✓✗✓✗ |
1 |
addCommand("setTimeToStart", |
78 |
✓✗ | 1 |
makeDirectSetter( |
79 |
*this, &time_to_start_, |
||
80 |
✓✗✓✗ ✓✗ |
2 |
docDirectSetter("Time to start of the buffer", "double"))); |
81 |
1 |
} |
|
82 |
|||
83 |
1 |
void SimpleSeqPlay::load(const std::string& filename) { |
|
84 |
1 |
state_ = 0; |
|
85 |
|||
86 |
using boost::escaped_list_separator; |
||
87 |
typedef boost::tokenizer<escaped_list_separator<char> > tokenizer_t; |
||
88 |
2 |
std::string line; |
|
89 |
2 |
std::string fn; |
|
90 |
|||
91 |
✓✗ | 2 |
std::ifstream file; |
92 |
1 |
unsigned int lineNumber = 0; |
|
93 |
1 |
int postureSize = -2; |
|
94 |
✓✗ | 1 |
fn = filename + ".posture"; |
95 |
// Open file |
||
96 |
✓✗ | 1 |
file.open(fn.c_str()); |
97 |
✓✗✗✓ |
1 |
if (!file.is_open()) { |
98 |
throw std::runtime_error(std::string("Failed to open file ") + fn); |
||
99 |
} |
||
100 |
|||
101 |
1 |
posture_.clear(); |
|
102 |
|||
103 |
// Read posture |
||
104 |
✓✗✓✗ |
6201 |
while (file.good()) { |
105 |
✓✗ | 6201 |
std::getline(file, line); |
106 |
6201 |
++lineNumber; |
|
107 |
✓✗✓✗ |
6201 |
tokenizer_t tok(line, escaped_list_separator<char>('\\', ' ', '\"')); |
108 |
6201 |
std::vector<double> components; |
|
109 |
✓✗✓✗ ✓✗✓✓ |
210801 |
for (tokenizer_t::iterator it = tok.begin(); it != tok.end(); ++it) { |
110 |
✓✗✓✗ ✓✗ |
204600 |
components.push_back(atof(it->c_str())); |
111 |
} |
||
112 |
✓✓ | 6201 |
if (components.size() == 0) { |
113 |
1 |
break; |
|
114 |
} |
||
115 |
✓✓ | 6200 |
if (postureSize == -2) { |
116 |
1 |
postureSize = static_cast<int>(components.size() - 1); |
|
117 |
} else { |
||
118 |
✗✓ | 6199 |
if (postureSize != static_cast<int>(components.size()) - 1) { |
119 |
std::ostringstream oss; |
||
120 |
oss << fn << ", line " << lineNumber << ": config of size " |
||
121 |
<< components.size() - 1 << ". Expecting " << postureSize << "."; |
||
122 |
throw std::runtime_error(oss.str()); |
||
123 |
} |
||
124 |
} |
||
125 |
✓✗ | 12400 |
dg::Vector config(static_cast<unsigned>(components.size() - 1)); |
126 |
✓✓ | 204600 |
for (unsigned i = 1; i < components.size(); ++i) { |
127 |
✓✗ | 198400 |
config(i - 1) = components[i]; |
128 |
} |
||
129 |
✓✗ | 6200 |
posture_.push_back(config); |
130 |
} |
||
131 |
✓✗ | 1 |
file.close(); |
132 |
1 |
} |
|
133 |
|||
134 |
1 |
void SimpleSeqPlay::start() { |
|
135 |
✓✗ | 1 |
if (state_ == 0) { |
136 |
1 |
state_ = 1; |
|
137 |
1 |
startTime_ = postureSOUT_.getTime(); |
|
138 |
} |
||
139 |
1 |
} |
|
140 |
|||
141 |
6200 |
dg::Vector& SimpleSeqPlay::computePosture(dg::Vector& pos, int t) { |
|
142 |
std::size_t configId; |
||
143 |
// If we are still waiting to start |
||
144 |
✗✓ | 6200 |
if (state_ == 0) { |
145 |
// return the current posture. |
||
146 |
pos = currentPostureSIN_.access(t); |
||
147 |
return pos; |
||
148 |
} |
||
149 |
✗✓ | 6200 |
if (posture_.size() == 0) { |
150 |
throw std::runtime_error( |
||
151 |
"SimpleSeqPlay posture: Signals not initialized. read files first."); |
||
152 |
} |
||
153 |
|||
154 |
// Going to the first position |
||
155 |
✓✓ | 6200 |
if (state_ == 1) { |
156 |
// Compute the difference between current posture and desired one. |
||
157 |
✓✗✓✗ ✓✗ |
1 |
dg::Vector deltapos = posture_[0] - currentPostureSIN_.access(t); |
158 |
|||
159 |
// If sufficiently closed to the first posture of the seqplay. |
||
160 |
✓✗✗✓ ✓✗ |
1 |
if ((deltapos.norm() < 1e-4) || |
161 |
(((dt_ + 1) * it_nbs_in_state1_) > time_to_start_)) { |
||
162 |
// Switch to the next state. |
||
163 |
1 |
state_ = 2; |
|
164 |
1 |
startTime_ = postureSOUT_.getTime(); |
|
165 |
✓✗ | 1 |
pos = posture_[0]; |
166 |
} else { |
||
167 |
// Tries to go closer to the first posture. |
||
168 |
deltapos = (deltapos * dt_) / (time_to_start_ - dt_ * it_nbs_in_state1_); |
||
169 |
pos = currentPostureSIN_.access(t) + deltapos; |
||
170 |
it_nbs_in_state1_++; |
||
171 |
} |
||
172 |
1 |
return pos; |
|
173 |
} |
||
174 |
// Tries to go through the list of postures. |
||
175 |
✓✗ | 6199 |
else if (state_ == 2) { |
176 |
6199 |
configId = t - startTime_; |
|
177 |
✓✓ | 6199 |
if (configId == posture_.size() - 1) { |
178 |
1 |
state_ = 3; |
|
179 |
} |
||
180 |
} else { |
||
181 |
configId = posture_.size() - 1; |
||
182 |
} |
||
183 |
6199 |
pos = posture_[configId]; |
|
184 |
6199 |
return pos; |
|
185 |
} |
||
186 |
|||
187 |
1 |
bool SimpleSeqPlay::waiting() const { return state_ == 0; } |
|
188 |
1 |
bool SimpleSeqPlay::initializing() const { return state_ == 1; } |
|
189 |
6199 |
bool SimpleSeqPlay::executing() const { return state_ == 2; } |
|
190 |
1 |
bool SimpleSeqPlay::finished() const { return state_ == 3; } |
|
191 |
|||
192 |
std::string SimpleSeqPlay::getDocString() const { |
||
193 |
return "Provide joint references for a whole-body motion\n" |
||
194 |
"\n" |
||
195 |
" The reference trajectories of the joints are loaded from the file\n" |
||
196 |
" using command load.\n" |
||
197 |
"\n" |
||
198 |
" To use this entity,\n" |
||
199 |
" 1. call method load,\n" |
||
200 |
" 2. plug reference signals into robot signals and\n" |
||
201 |
" 3. call method start.\n" |
||
202 |
" Warning: pluging signals before loading trajectories will fail.\n"; |
||
203 |
} |
||
204 |
|||
205 |
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(SimpleSeqPlay, "SimpleSeqPlay"); |
||
206 |
} // namespace tools |
||
207 |
} // namespace sot |
||
208 |
} // namespace dynamicgraph |
Generated by: GCOVR (Version 4.2) |