From d01224736ca6aa0d4f757a9dde751a4ae3ab86c5 Mon Sep 17 00:00:00 2001 From: Andrea Censi <andrea@cds.caltech.edu> Date: Sat, 6 Feb 2010 07:38:21 +0000 Subject: [PATCH] added purify command --- sm/CMakeLists.txt | 1 + sm/apps/ld_purify.c | 87 +++++++++++++++++++++++++++++++++++++++++++ sm/apps/ld_resample.c | 42 ++++++++------------- sm/csm/laser_data.c | 2 +- 4 files changed, 105 insertions(+), 27 deletions(-) create mode 100644 sm/apps/ld_purify.c diff --git a/sm/CMakeLists.txt b/sm/CMakeLists.txt index 56cb187..87a8818 100644 --- a/sm/CMakeLists.txt +++ b/sm/CMakeLists.txt @@ -98,6 +98,7 @@ new_executable(ld_remove_doubles) new_executable(ld_alternate) new_executable(ld_recover) +new_executable(ld_purify) new_executable(ld_select) new_executable(ld_cluster_curv) new_executable(ld_linearize) diff --git a/sm/apps/ld_purify.c b/sm/apps/ld_purify.c new file mode 100644 index 0000000..53de455 --- /dev/null +++ b/sm/apps/ld_purify.c @@ -0,0 +1,87 @@ +#include <gsl/gsl_rng.h> +#include <gsl/gsl_randist.h> + +#include <math.h> +#include <libgen.h> + +#include <options/options.h> +#include "../csm/csm_all.h" + +void purify(LDP ld, double threshold_min, double threshold_max); + + +struct ld_purify_params { + double threshold_min, threshold_max; + const char* file_input; + const char* file_output; +}; + + +int main(int argc, const char * argv[]) { + sm_set_program_name(argv[0]); + + + options_banner("ld_purify: Makes sure that the file format is valid. \n * Sets valid=0 if reading is outside interval "); + + struct ld_purify_params p; + + struct option* ops = options_allocate(20); + options_double(ops, "threshold_min", &p.threshold_min, 0.01, + "Sets valid=0 if readings are less than this threshold."); + options_double(ops, "threshold_max", &p.threshold_max, 79.0, + "Sets valid=0 if readings are more than this threshold."); + + options_string(ops, "in", &p.file_input, "stdin", "Input file "); + options_string(ops, "out", &p.file_output, "stdout", "Output file "); + + + if(!options_parse_args(ops, argc, argv)) { + options_print_help(ops, stderr); + return -1; + } + + FILE * in = open_file_for_reading(p.file_input); + if(!in) return -3; + + FILE * out = open_file_for_writing(p.file_output); + if(!out) return -2; + + + + LDP ld; int count = -1; + while( (ld = ld_from_json_stream(in))) { + + purify(ld, p.threshold_min, p.threshold_max); + + if(!ld_valid_fields(ld)) { + sm_error("Wait, we didn't purify enough (#%d in file)\n", count); + continue; + } + + ld_write_as_json(ld, out); + ld_free(ld); + } + + return 0; +} + + + +void purify(LDP ld, double threshold_min, double threshold_max) { + for(int i=0;i<ld->nrays;i++) { + if(!ld->valid[i]) continue; + + double rho = ld->readings[i]; + if( is_nan(rho) | (rho < threshold_min) | (rho > threshold_max) ) { + ld->readings[i] = GSL_NAN; + ld->valid[i] = 0; + ld->alpha[i] = GSL_NAN; + ld->alpha_valid[i] = 0; + } + + } + +} + + + diff --git a/sm/apps/ld_resample.c b/sm/apps/ld_resample.c index e6b600b..95b8620 100644 --- a/sm/apps/ld_resample.c +++ b/sm/apps/ld_resample.c @@ -24,27 +24,11 @@ int main(int argc, const char ** argv) { struct option* ops = options_allocate(3); options_double(ops, "interval", &p.interval, sqrt(2.0), " 1 = no resampling"); - options_int(ops, "seed", &p.seed, 0, - "Seed for random number generator (if 0, use GSL_RNG_SEED env. variable)."); - if(!options_parse_args(ops, argc, argv)) { -/* fprintf(stderr, "A simple program for adding slip to odometry \n\n" - "The 'odometry' field is set to 'true_pose' + noise.\n" - "If 'true_pose' is not available, then the 'odometry' \n" - "field is set to 'odometry' + noise.\n\n" - "Note: this program does *not* simulate the effect of \n" - "slip or odometry error in a realistic way; each scan \n" - "in the file is considered separately, the error does \n" - "not depend on the traveled distance, etc.\n\n");*/ options_print_help(ops, stderr); return -1; } - gsl_rng_env_setup(); - rng = gsl_rng_alloc (gsl_rng_ranlxs0); - if(p.seed != 0) - gsl_rng_set(rng, (unsigned int) p.seed); - int count = -1; LDP ld; while( (ld = ld_read_smart(stdin))) { @@ -73,27 +57,33 @@ int main(int argc, const char ** argv) { LDP ld_resample(LDP ld) { /* FIXME magic number */ - int n = (int) (floor(ld->nrays / p.interval))-4; + int n = (int) (floor(ld->nrays / p.interval)); LDP ld2 = ld_alloc_new(n); int k; for(k=0;k<n;k++) { double index = k * p.interval; int i = (int) floor(index); + int j = i + 1; double a = 1 - (index - i); - - ld2->theta[k] = a * ld->theta[i] + (1-a) * ld->theta[i+1]; - - if(is_nan(ld2->theta[k])) { - sm_debug("Hey, k=%d theta[%d]=%f theta[%d]=%f\n", - k,i,ld->theta[i],i+1,ld->theta[i+1]); - } + - if(!ld->valid[i] || !ld->valid[i+1]) { + if( (j>= ld->nrays) || !ld->valid[i] || !ld->valid[j]) { ld2->valid[k] = 0; ld2->readings[k] = NAN; + ld2->alpha_valid[k] = 0; + ld2->alpha[k] = NAN; + ld2->theta[k] = ld->theta[i]; } else { - ld2->readings[k] = a * ld->readings[i] + (1-a) * ld->readings[i+1]; + ld2->theta[k] = a * ld->theta[i] + (1-a) * ld->theta[j]; + + + if(is_nan(ld2->theta[k])) { + sm_debug("Hey, k=%d theta[%d]=%f theta[%d]=%f\n", + k,i,ld->theta[i],j,ld->theta[j]); + } + + ld2->readings[k] = a * ld->readings[i] + (1-a) * ld->readings[j]; ld2->valid[k] = 1; } diff --git a/sm/csm/laser_data.c b/sm/csm/laser_data.c index 6e6820b..7f47fb7 100644 --- a/sm/csm/laser_data.c +++ b/sm/csm/laser_data.c @@ -230,7 +230,7 @@ int ld_valid_fields(LDP ld) { } else { /* ray not valid, but checking theta anyway */ if(is_nan(th)) { - sm_error("Ray #%d: valid = %d but theta = %f", + sm_error("Ray #%d: valid = %d but theta = %f\n", i, ld->valid[i], th); return 0; } -- GitLab