Exemple #1
0
/**
* Performs a simulation step for the given duration, by moving
* our simulated position in a circle at a given radius and speed
* around the simulation's center point.
*/
void simulation_step_position_in_circle(double elapsed)
{

  /* Update the angle, making a small angle approximation. */
  sim_state.angle += (sim_settings.speed * elapsed) / sim_settings.radius;
  if (sim_state.angle > 2*M_PI) {
    sim_state.angle = 0;
  }

  double pos_ned[3] = {
    sim_settings.radius * sin(sim_state.angle),
    sim_settings.radius * cos(sim_state.angle),
    0
  };

  /* Fill out position simulation's gnss_solution pos_ECEF, pos_LLH structures */
  wgsned2ecef_d(pos_ned,
    sim_settings.base_ecef,
    sim_state.pos);

  /* Calculate an accurate baseline for simulating RTK */
  vector_subtract(3,
    sim_state.pos,
    sim_settings.base_ecef,
    sim_state.baseline);

  /* Add gaussian noise to PVT position */
  double* pos_ecef = sim_state.noisy_solution.pos_ecef;
  double pos_variance = sim_settings.pos_sigma * sim_settings.pos_sigma;
  pos_ecef[0] = sim_state.pos[0] + rand_gaussian(pos_variance);
  pos_ecef[1] = sim_state.pos[1] + rand_gaussian(pos_variance);
  pos_ecef[2] = sim_state.pos[2] + rand_gaussian(pos_variance);

  wgsecef2llh(sim_state.noisy_solution.pos_ecef, sim_state.noisy_solution.pos_llh);

  /* Calculate Velocity vector tangent to the sphere */
  double noisy_speed = sim_settings.speed +
                       rand_gaussian(sim_settings.speed_sigma *
                                     sim_settings.speed_sigma);

  sim_state.noisy_solution.vel_ned[0] = noisy_speed * cos(sim_state.angle);
  sim_state.noisy_solution.vel_ned[1] = noisy_speed * -1.0 * sin(sim_state.angle);
  sim_state.noisy_solution.vel_ned[2] = 0.0;

  wgsned2ecef(sim_state.noisy_solution.vel_ned,
    sim_state.noisy_solution.pos_ecef,
    sim_state.noisy_solution.vel_ecef);
}
/** For a point given in the local North, East, Down (NED) frame of a provided
 * ECEF reference point, return the vector to that point in ECEF coordinates.
 *
 * Intended for calculating a new ECEF position. For converting velocity vectors,
 * \see wgsned2ecef.
 *
 * \param ned       The North, East, Down vector is passed as [N, E, D], all in
 *                  meters.
 * \param ref_ecef  Cartesian coordinates of the reference point, passed as
 *                  [X, Y, Z], all in meters.
 * \param ecef      Cartesian coordinates of the point written into this array,
 *                  [X, Y, Z], all in meters.
 */
void wgsned2ecef_d(const double ned[3], const double ref_ecef[3],
                   double ecef[3]) {
  double tempv[3];
  wgsned2ecef(ned, ref_ecef, tempv);
  vector_add(3, tempv, ref_ecef, ecef);
}