-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcreator.cpp
264 lines (236 loc) · 8.21 KB
/
creator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
//===============================================================================//
// Name : creator.cpp
// Author(s) : Barbara Bruno, Antonello Scalmato
// Affiliation : University of Genova, Italy - dept. DIBRIS
// Version : 2.0
// Description : Human Motion Primitives models creator module (off-line only)
//===============================================================================//
#include <fstream>
#include "creator.hpp"
#include "libs/GMM+GMR/gmr.h"
//! constructor of class STmodel
//! @param[in] n name of the motion primitive
//! @param[in] nbMT number of trials in the modelling folder
//! @param[in] nbGG number of Gaussians modelling gravity
//! @param[in] nbBG number of Gaussians modelling body acc.
STmodel::STmodel(string n, int nbMT, int nbGG, int nbBG)
{
name = n;
nbModellingTrials = nbMT;
nbGravityGaussians = nbGG;
nbBodyGaussians = nbBG;
}
//! print model information
void STmodel::printInfo()
{
cout<<"STmodel object information:" <<endl;
cout<<"name = " <<name <<endl;
cout<<"nbModellingTrials = " <<nbModellingTrials <<endl;
cout<<"nbGravityGaussians = " <<nbGravityGaussians <<endl;
cout<<"nbBodyGaussians = " <<nbBodyGaussians <<endl;
}
//! constructor of class Creator
//! @param[in] dF folder containing the modelling dataset
//! @param[in] dev driver for the device used for the dataset collection
Creator::Creator(string dF, Device* dev)
{
const char* home = getenv("HOME");
if (home)
{
std::string path(home);
path += "/HMPdetector/Models/";
datasetFolder = path + dF + "/";
cout<<"Modelling dataset in folder: " <<datasetFolder <<endl;
}
else
{
cout << "ERROR: path not found"<<endl;
}
driver = dev;
//DEBUG:driver->printInfo();
}
//! set dataset folder
//! @param[in] dF folder containing the modelling dataset
void Creator::setDatasetFolder(string dF)
{
const char* home = getenv("HOME");
if (home)
{
std::string path(home);
path += "/HMPdetector/Models/";
datasetFolder = path + dF + "/";
cout<<"Modelling dataset in folder: " <<datasetFolder <<endl;
}
else
{
cout << "ERROR: path not found"<<endl;
}
}
//! concatenate the trials of the modelling dataset along the three axes
//! @param[in] &actual_sample one sample from one modelling trial
//! @param[out] &set set of all the modelling trials samples
void Creator::createSet(mat &actual_sample, mat &set)
{
set = join_cols(set, actual_sample);
}
//! extract gravity and body acc. components from the dataset
//! @param[in] name name of the motion primitive
//! @param[in] nTr number of trials in the modelling dataset
//! @param[out] &totGravity reference to the gravity set of the modelling trials
//! @param[out] &totBody reference to the body acc. set of the modelling trials
void Creator::getFeatures(string name, int nTr, mat &totGravity, mat &totBody)
{
string fileName; // name of one trial of the modelling dataset
for (int i = 0; i < nTr; i++)
{
// read all the modelling trials and concatenate the values along the axes
stringstream itos;
itos <<i+1;
fileName = datasetFolder + name + "/mod (" + itos.str() + ").txt";
cout<<"Open modelling trial: " <<fileName <<endl;
mat set;
mat gravity;
mat body;
ifstream trialFile(fileName.c_str());
for (string line; std::getline(trialFile, line); )
{
// DEBUG:cout<<"Line: " <<line <<endl;
mat actualSample;
actualSample = driver->extractActual(line);
createSet(actualSample, set);
}
// std::cout<<"Set:"<<std::endl;
// set.print();
// reduce the noise on the sets by median filtering
int size = 3;
mat clean_set = set.t();
medianFilter(clean_set, size);
clean_set = clean_set.t();
// std::cout<<"clean_set"<<std::endl;
// clean_set.print();
// separate gravity and body acc. by Chebyshev II low-pass filtering
mat tempgr = clean_set.t();
gravity = ChebyshevFilter(tempgr);
// std::cout<<"gravity"<<std::endl;
// gravity.print();
gravity = gravity.t();
body = clean_set - gravity;
// std::cout<<"gravity"<<std::endl;
// gravity.print();
// std::cout<<"body"<<std::endl;
// body.print();
// create the datasets
mat time = createInterval(1, gravity.n_rows);
mat tmpGrav = join_rows(time, gravity);
mat tmpBody = join_rows(time, body);
totGravity = join_cols(totGravity, tmpGrav);
totBody = join_cols(totBody, tmpBody);
}
}
//! create the model of one motion primitive (with GMM+GMR)
//! @param[in] &motion motion primitive settings object
void Creator::generateModel(STmodel &motion)
{
mat totGravity;
mat totBody;
string GMMgravity;
string GMMbody;
string MuGr;
string MuBo;
string SGr;
string SBo;
// create the gravity and body acc. datasets
cout<<endl <<"Creating the gravity and body acceleration datasets" <<endl;
getFeatures(motion.name, motion.nbModellingTrials, totGravity, totBody);
std::cout<<"totGravity"<<std::endl;
totGravity.print();
// create the GMM+GMR model of the gravity component
{
cout<<endl <<"GMM+GMR model of the gravity component" <<endl;
GaussianMixture gg;
int nbVar = totGravity.n_cols;
int nbData = totGravity.n_rows;
nbData = (int) (nbData / motion.nbModellingTrials);
cout<<"Number of samples in the modelling trials: " <<nbData <<endl;
// GMM phase
cout<<endl <<"GMM...";
gg.initEM_TimeSplitMat(motion.nbGravityGaussians, totGravity);
gg.doEM(totGravity);
GMMgravity = datasetFolder + motion.name + "GMMgravity.txt";
gg.saveParams(GMMgravity.c_str());
cout <<"done" <<endl;
// GMR phase
cout<<endl <<"GMR...";
Vector inC(1), outC(nbVar - 1);
// input data for regression: time
inC(0) = 0;
// output data for regression: tri-axial acceleration
for (int i = 0; i < nbVar - 1; i++)
outC(i) = (float) (i + 1);
mat oneCol = createInterval(1,nbData);
Matrix *inData = new Matrix(oneCol);
Matrix *outSigma;
outSigma = new Matrix[nbData];
Matrix outData = gg.doRegression(*inData, outSigma, inC, outC);
MuGr = datasetFolder + motion.name + "MuGravity.txt";
SGr = datasetFolder + motion.name + "SigmaGravity.txt";
gg.saveRegressionResult(MuGr.c_str(),SGr.c_str(),*inData,outData,outSigma);
cout <<"done" <<endl;
}
// create the GMM+GMR model of the body acc. component
{
cout<<endl <<"GMM+GMR model of the body acc. component" <<endl;
GaussianMixture gb;
int nbVar = totBody.n_cols;
int nbData = totBody.n_rows;
nbData = (int) (nbData / motion.nbModellingTrials);
cout<<"Number of samples in the modelling trials: " <<nbData <<endl;
// GMM phase
cout<<endl <<"GMM...";
gb.initEM_TimeSplitMat(motion.nbBodyGaussians, totBody);
gb.doEM(totBody);
GMMbody = datasetFolder + motion.name + "GMMbody.txt";
gb.saveParams(GMMbody.c_str());
cout <<"done" <<endl;
// GMR phase
cout<<endl <<"GMR...";
Vector inC(1), outC(nbVar - 1);
// input data for regression: time
inC(0) = 0;
// output data for regression: tri-axial acceleration
for (int i = 0; i < nbVar - 1; i++)
outC(i) = (float) (i + 1);
mat oneCol = createInterval(1,nbData);
Matrix *inData = new Matrix(oneCol);
Matrix *outSigma;
outSigma = new Matrix[nbData];
Matrix outData = gb.doRegression(*inData, outSigma, inC, outC);
MuBo = datasetFolder + motion.name + "MuBody.txt";
SBo = datasetFolder + motion.name + "SigmaBody.txt";
gb.saveRegressionResult(MuBo.c_str(),SBo.c_str(),*inData,outData,outSigma);
cout <<"done" <<endl;
}
}
//! create the models of all motion primitives
void Creator::generateAllModels()
{
string one_n;
int one_nbMT;
int one_nbGG;
int one_nbBG;
cout<<"****************************"<<endl;
string fileName = datasetFolder + "HMPconfig.txt";
cout<<"config file: " <<fileName <<endl;
ifstream configFile(fileName.c_str());
while (!configFile.eof())
{
configFile>>one_n >>one_nbMT >>one_nbGG >>one_nbBG;
if (!configFile)
break;
cout<<"Generating model: " <<one_n <<endl;
STmodel one_HMP(one_n,one_nbMT,one_nbGG,one_nbBG);
one_HMP.printInfo();
generateModel(one_HMP);
}
configFile.close();
}