14 using Eigen::VectorXf;
15 using Eigen::MatrixXf;
21 void GPNodelet::init_gp()
24 gp_mean_.resize(size_gp_, 1);
25 gp_cov_ = MatrixXf::Zero(size_gp_, size_gp_);
27 for (
unsigned int k = 0; k < size_gp_; k++) {
28 gp_mean_(k) = gp_init_mean_;
29 gp_cov_(k, k) = 1/gp_noise_var_;
34 x_coord_.resize(size_gp_);
35 y_coord_.resize(size_gp_);
37 for (
int k = 0; k < size_gp_; k++) {
42 if (y > size_wall_y_ + 0.01) {
49 gp_C_.resize(size_gp_, size_gp_);
50 double inv_var = 1/gp_noise_var_;
52 for (
int k = 0; k < size_gp_; k++) {
53 for (
int l = 0; l <= k; l++) {
54 gp_C_(k, l) = matern_kernel(x_coord_(k), y_coord_(k), x_coord_(l), y_coord_(l));
55 gp_C_(l, k) = gp_C_(k, l);
58 gp_C_(k, k) += inv_var;
61 gp_C_inv_ = gp_C_.inverse();
65 void GPNodelet::pop_reordered_idx(
66 unsigned int size_obs,
unsigned int size_nobs,
67 unsigned int min_x,
unsigned int max_x,
unsigned int min_y,
unsigned int max_y,
68 vector<unsigned int> &idx_obs , vector<unsigned int> &idx_nobs)
const 70 idx_obs.resize(size_obs);
71 idx_nobs.resize(size_nobs);
76 for (
unsigned int i = min_x; i <= max_x; i++) {
77 for (
unsigned int j = min_y; j <= max_y; j++) {
78 idx_obs[k] = i*size_gp_y_ + j;
88 while (m < size_gp_) {
107 void GPNodelet::notif_changing_pxls(
const RectArea &coord)
110 float delta_x = size_wall_x_ / (size_img_x_-1);
111 float delta_y = size_wall_y_ / (size_img_y_-1);
114 for (
unsigned int i = 0; i < size_img_x_; i++) {
115 for (
unsigned int j = 0; j < size_img_y_; j++) {
116 if (x >= coord.
min_x && x <= coord.max_x && y >= coord.
min_y 117 && y <= coord.
max_y) {
118 changed_pxl_[k] =
true;
131 void GPNodelet::build_Kalman_objects(
132 const vector<unsigned int> &idx_obs,
133 const vector<unsigned int> &idx_nobs,
134 VectorXf &mu, VectorXf &mu_obs,
135 MatrixXf &
P, MatrixXf &P_obs, MatrixXf &B,
136 MatrixXf &C_obs, MatrixXf &C_obs_inv,
137 VectorXf &x_coord, VectorXf &y_coord)
const 139 unsigned int size_obs = idx_obs.size();
140 unsigned int size_nobs = idx_nobs.size();
142 for (
unsigned int k = 0; k < size_obs; k++) {
143 mu_obs(k) = gp_mean_(idx_obs[k]);
145 for (
unsigned int l = 0; l <= k; l++) {
146 P_obs(k, l) = gp_cov_(idx_obs[k], idx_obs[l]);
147 P_obs(l, k) = P_obs(k, l);
149 C_obs(k, l) = gp_C_(idx_obs[k], idx_obs[l]);
150 C_obs(l, k) = C_obs(k, l);
153 for (
unsigned int l = 0; l < size_nobs; l++) {
154 B(k, l) = gp_cov_(idx_obs[k], idx_nobs[l]);
157 x_coord(k) = x_coord_(idx_obs[k]);
158 y_coord(k) = y_coord_(idx_obs[k]);
161 for (
unsigned int k = 0; k < size_gp_; k++) {
167 corr_k = idx_nobs[k - size_obs];
169 mu(k) = gp_mean_(corr_k);
171 for (
unsigned int l = 0; l <= k; l++) {
177 corr_l = idx_nobs[l - size_obs];
179 P(k, l) = gp_cov_(corr_k, corr_l);
184 C_obs_inv = C_obs.inverse();
188 void GPNodelet::update_reordered_gp(
189 const vector<unsigned int> &idx_obs,
190 const vector<unsigned int> &idx_nobs,
191 const VectorXf &mu,
const MatrixXf &
P,
192 Eigen::VectorXf &gp_mean, Eigen::MatrixXf &gp_cov)
const 194 unsigned int size_obs = idx_obs.size();
195 unsigned int size_nobs = idx_nobs.size();
197 for (
unsigned int k = 0; k < size_gp_; k++) {
203 corr_k = idx_nobs[k - size_obs];
205 gp_mean(corr_k) = mu(k);
207 for (
unsigned int l = 0; l <= k; l++) {
213 corr_l = idx_nobs[l - size_obs];
215 if (corr_k == corr_l &&
P(k, l) > gp_cov_thresh_) {
216 gp_cov(corr_k, corr_l) =
P(k, l);
217 gp_cov(corr_l, corr_k) =
P(l, k);
219 else if (corr_k == corr_l) {
221 gp_cov(corr_k, corr_l) = gp_cov_thresh_;
222 gp_cov(corr_l, corr_k) = gp_cov_thresh_;
226 gp_cov(corr_k, corr_l) = 0;
227 gp_cov(corr_l, corr_k) = 0;
234 void GPNodelet::update_gp(
237 Eigen::VectorXf &gp_mean, Eigen::MatrixXf &gp_cov,
238 vector<unsigned int> &idx_obs,
240 bool update_mean)
const 244 if (x_meas.size() == 0)
247 float min_x = *std::min_element(x_meas.begin(), x_meas.end());
248 float min_y = *std::min_element(y_meas.begin(), y_meas.end());
249 float max_x = *std::max_element(x_meas.begin(), x_meas.end());
250 float max_y = *std::max_element(y_meas.begin(), y_meas.end());
252 min_x = max(
float(0), min_x - radius_obs_);
253 max_x = min(
float(size_wall_x_), max_x + radius_obs_);
254 min_y = max(
float(0), min_y - radius_obs_);
255 max_y = min(
float(size_wall_y_), max_y + radius_obs_);
257 unsigned int min_obs_x = min_x / delta_x_;
258 unsigned int max_obs_x = max_x / delta_x_;
259 unsigned int min_obs_y = min_y / delta_y_;
260 unsigned int max_obs_y = max_y / delta_y_;
261 unsigned int size_obs_x = max_obs_x - min_obs_x + 1;
262 unsigned int size_obs_y = max_obs_y - min_obs_y + 1;
263 unsigned int size_obs = size_obs_x * size_obs_y;
264 unsigned int size_nobs = size_gp_ - size_obs;
266 idx_obs.resize(size_obs, 0);
267 vector<unsigned int> idx_nobs(size_nobs, 0);
268 pop_reordered_idx(size_obs, size_nobs, min_obs_x, max_obs_x, min_obs_y, max_obs_y,
272 obs_coord.
min_x = min_x;
273 obs_coord.
max_x = max_x;
274 obs_coord.
min_y = min_y;
275 obs_coord.
max_y = max_y;
278 VectorXf mu(size_gp_);
279 VectorXf mu_obs(size_obs);
280 MatrixXf
P(size_gp_, size_gp_);
281 MatrixXf P_obs(size_obs, size_obs);
282 MatrixXf B(size_obs, size_nobs);
283 MatrixXf C_obs(size_obs, size_obs);
284 MatrixXf C_obs_inv(size_obs, size_obs);
285 VectorXf x_coord(size_obs);
286 VectorXf y_coord(size_obs);
288 build_Kalman_objects(idx_obs, idx_nobs, mu, mu_obs, P, P_obs, B, C_obs, C_obs_inv,
292 int size_meas = values.size();
293 VectorXf z(size_meas);
294 MatrixXf R = MatrixXf::Zero(size_meas, size_meas);
296 for (
unsigned int k = 0; k < size_meas; k++) {
298 R(k, k) = camera_noise(distances[k]);
302 MatrixXf k_meas(size_meas, size_obs);
304 for (
unsigned int i = 0; i < size_meas; i++) {
305 for (
unsigned int j = 0; j < size_obs; j++) {
306 k_meas(i, j) = matern_kernel(
307 x_meas[i], y_meas[i], x_coord(j), y_coord(j)
312 MatrixXf H_obs = k_meas * C_obs_inv;
316 v = z - H_obs * mu_obs;
319 MatrixXf PHt(size_obs, size_meas);
320 MatrixXf BtHt(size_nobs, size_meas);
321 MatrixXf L(size_gp_, size_meas);
323 PHt = P_obs * H_obs.transpose();
324 BtHt = B.transpose() * H_obs.transpose();
328 MatrixXf S = H_obs * PHt + R;
329 MatrixXf S_inv = S.inverse();
330 MatrixXf K = L * S_inv;
335 P = P - L * S_inv * L.transpose();
337 update_reordered_gp(idx_obs, idx_nobs, mu, P, gp_mean, gp_cov);
340 min_x = max(
float(0), min_x - radius_obs_);
341 max_x = min(
float(size_wall_x_), max_x + radius_obs_);
342 min_y = max(
float(0), min_y - radius_obs_);
343 max_y = min(
float(size_wall_y_), max_y + radius_obs_);
345 min_obs_x = min_x / delta_x_;
346 max_obs_x = max_x / delta_x_;
347 min_obs_y = min_y / delta_y_;
348 max_obs_y = max_y / delta_y_;
350 size_obs = (max_obs_x - min_obs_x + 1) * (max_obs_y - min_obs_y + 1);
351 size_nobs = size_gp_ - size_obs;
353 pop_reordered_idx(size_obs, size_nobs, min_obs_x, max_obs_x, min_obs_y, max_obs_y, idx_obs, idx_nobs);
358 void GPNodelet::prepare_eval(
359 const std::vector<unsigned int> &idx_obs,
360 const Eigen::VectorXf &gp_mean,
361 Eigen::VectorXf &x_obs, Eigen::VectorXf &y_obs,
362 Eigen::VectorXf &W)
const 364 unsigned int size_obs = idx_obs.size();
365 VectorXf mu_obs(size_obs);
366 MatrixXf C_inv_obs(size_obs, size_obs);
367 x_obs = VectorXf(size_obs);
368 y_obs = VectorXf(size_obs);
370 for (
unsigned int k = 0; k < size_obs; k++) {
371 mu_obs(k) = gp_mean(idx_obs_[k]);
372 x_obs(k) = x_coord_(idx_obs_[k]);
373 y_obs(k) = y_coord_(idx_obs_[k]);
375 for (
unsigned int l = 0; l <= k; l++) {
376 C_inv_obs(k, l) = gp_C_inv_(idx_obs_[k], idx_obs_[l]);
377 C_inv_obs(l, k) = C_inv_obs(k, l);
381 W = C_inv_obs * mu_obs;
385 float GPNodelet::eval_gp(
387 const Eigen::VectorXf &x_obs,
const Eigen::VectorXf &y_obs,
388 const Eigen::VectorXf &W)
const 390 int size_obs = x_obs.size();
391 Eigen::VectorXf k_obs(size_obs);
393 for (
unsigned int l = 0; l < size_obs; l++) {
394 k_obs(l) = matern_kernel(
395 x, y, x_obs(l), y_obs(l)
399 float gp_value = k_obs.dot(W);
400 return (1/(1 + exp(-out_scale_*(gp_value - 0.5))));
Declaration of a nodelet for Gaussian Process mapping of an algae wall.
std::vector< float > vec_f