ゲイン計算

static auto calc_gain = [&]() {
      double v = hypot(estimate_vel_.x, estimate_vel_.y);//並進速度
      double angular = fabs(estimate_vel_.theta);//角速度
      v = std::clamp(v, 0.0, MAX_VEL);
      angular = std::clamp(angular, 0.0, MAX_ANGULAR);
      // 遅いときlrf 速いときオドメトリ
      double gain_xy = ((MAX_GAIN_XY - MIN_GAIN_XY) / MAX_VEL) * v + MIN_GAIN_XY;
      double gain_theta = ((MAX_GAIN_THETA - MIN_GAIN_THETA) / MAX_ANGULAR) * angular + MIN_GAIN_THETA;
      // 遅いときオドメトリ 速いときlrf
      // double gain_xy = MAX_GAIN_XY - ((MAX_GAIN_XY - MIN_GAIN_XY) / MAX_VEL) * v;
      // double gain_theta = MAX_GAIN_THETA - ((MAX_GAIN_THETA - MIN_GAIN_THETA) / MAX_ANGULAR) * angular;
      return std::pair<double, double>(gain_xy, gain_theta);
    };

基準格子点更新

static auto update_reference_grid = [&]() {
      auto old_grid_point = reference_grid_point_;
      reference_grid_point_.x = std::round(odometer_pos_.x / GRID_WIDTH) * GRID_WIDTH;
      reference_grid_point_.y = std::round(odometer_pos_.y / GRID_WIDTH) * GRID_WIDTH;
      auto initial_pos_xy = initial_pos_.make_vector2() - old_grid_point.get_rotated(initial_pos_.theta) +
                            reference_grid_point_.get_rotated(initial_pos_.theta);
      initial_pos_.x = initial_pos_xy.x;
      initial_pos_.y = initial_pos_xy.y;
      auto q = odometer_pos_.make_vector2() - reference_grid_point_;
      q.rotate(initial_pos_.theta);
      return q;
    };

LRFからの自己位置取得

auto q = update_reference_grid();
const auto &[gain_xy, gain_theta] = calc_gain();
initial_pos_.x -= gain_xy * (q.x + initial_pos_.x - laser_pos_.x);
initial_pos_.y -= gain_xy * (q.y + initial_pos_.y - laser_pos_.y);
initial_pos_.theta = Angle(initial_pos_.theta -
	gain_theta * (double)Angle(odometer_pos_.theta + initial_pos_.theta - laser_pos_.theta));

メインループ

auto q = update_reference_grid();
estimate_pos_.x = initial_pos_.x + q.x;
estimate_pos_.y = initial_pos_.y + q.y;
estimate_pos_.theta = Angle(initial_pos_.theta + odometer_pos_.theta);