def plot(self, errs=None):
        time_samples = np.linspace(self.T_L_I.node_times[1] + 0.1,
                                   self.T_L_I.node_times[-3] - 0.1, 1000)

        # Plot initial situation (xy and in time):
        plt.figure(0)
        imu_positions = np.array(
            [self.T_L_I.sample(t).t.ravel() for t in time_samples])
        prism_positions = np.array([
            (self.T_L_I.sample(t) * self.alignment.p_I_P).ravel()
            for t in time_samples
        ])
        plots.xyPlot(imu_positions, prism_positions, self.p_L_Ps)
        plt.title('x,y trajectory of %s' % flags.sequenceSensorString())

        plt.figure(1)
        plots.xyztPlot(time_samples, imu_positions, prism_positions,
                       self.t_G0_Ps(), self.p_L_Ps)
        plt.title('x,y,z trajectory of %s' % flags.sequenceSensorString())

        if errs is not None:
            plt.figure(2)
            plt.semilogx(sorted(errs),
                         np.arange(len(errs), dtype=float) / len(errs))
            plt.grid()
            plt.xlabel('Leica error [m]')
            plt.ylabel('Fraction of measurements with smaller error')
            plt.title('Cumulative distribution of Leica error for %s' %
                      flags.sequenceSensorString())

        plt.show()
def callback(sequence_i):
    if sequence_i % FLAGS.num_workers == FLAGS.worker_i:
        if FLAGS.bag:
            print('De-ground truthing %s bag...' %
                  flags.sequenceSensorString())
            deGroundTruthBag()
        if FLAGS.zip:
            print('De-ground truthing %s zip...' %
                  flags.sequenceSensorString())
            deGroundTruthZip()
def callback(sequence_i):
    if sequence_i % FLAGS.num_workers == FLAGS.worker_i:
        if FLAGS.bag:
            if FLAGS.redo_min_bags or not os.path.exists(
                    flags.minImuGroundTruthOdometryBagPath()):
                print('Generating min bag for %s' %
                      flags.sequenceSensorString())
                makeMinImuGtoBag()
            print('Comparing bag gyro for %s' % flags.sequenceSensorString())
            compareGyro()
        if FLAGS.zip:
            print('Checking zip looks same as bag for %s' %
                  flags.sequenceSensorString())
            checkZipIsSameAsBag()
示例#4
0
def compareGyro():
    gyro_stamps = []
    gyros = []

    gt_attitude_stamps = []
    gt_attitudes = []

    if not os.path.exists(flags.minImuGroundTruthOdometryBagPath()):
        raise Exception('Run make_min_imu_gto_bag first!')
    bag = rosbag.Bag(flags.minImuGroundTruthOdometryBagPath())

    for bag_msg in bag:
        msg = bag_msg.message
        if bag_msg.topic == flags.imuTopic():
            gyro_stamps.append(msg.header.stamp)
            gyros.append(np.array([msg.angular_velocity.x,
                                   msg.angular_velocity.y,
                                   msg.angular_velocity.z]))
        if bag_msg.topic == '/groundtruth/odometry':
            gt_attitude_stamps.append(msg.header.stamp)
            gt_attitudes.append(pyquaternion.Quaternion(
                msg.pose.pose.orientation.w,
                msg.pose.pose.orientation.x,
                msg.pose.pose.orientation.y,
                msg.pose.pose.orientation.z))

    gyro_times = [(i - gyro_stamps[0]).to_sec() for i in gyro_stamps]
    gt_times = [(i - gyro_stamps[0]).to_sec() for i in gt_attitude_stamps]

    if FLAGS.gt_from_txt != '':
        print('Loading custom ground truth...')
        loaded = np.loadtxt(FLAGS.gt_from_txt)
        gt_attitude_stamps = None
        gt_times = loaded[:, 0] - gyro_stamps[0].to_sec()
        gt_attitudes = [pyquaternion.Quaternion(i[7], i[4], i[5], i[6]) for i in loaded]

    gt_Rs = [i.rotation_matrix for i in gt_attitudes]
    gt_twists = []
    for i in range(1, len(gt_attitudes) - 1):
        relative = np.dot(gt_Rs[i - 1].T, gt_Rs[i + 1])
        gt_twists.append(np.array([
            (relative[2, 1] - relative[1, 2]) / 2,
            (relative[0, 2] - relative[2, 0]) / 2,
            (relative[1, 0] - relative[0, 1]) / 2
        ]) / (gt_times[i + 1] - gt_times[i - 1]))

    plt.plot(gyro_times, [i[0] for i in gyros], '.')
    plt.plot(gt_times[1:-1], [i[0] for i in gt_twists])
    plt.grid()
    plt.title('x gyro to gt comparison %s' % flags.sequenceSensorString())
    plt.xlabel('Time[s]')
    plt.ylabel('Angular rate [rad]')
    plt.show()
示例#5
0
def callback(sequence_i):
    if FLAGS.sens == 'davis':
        plt.figure(0)
    else:
        assert FLAGS.sens == 'snap'
        plt.figure(1)

    files = flags.SplineLeicaAlignmentFiles('gt_leica_alignment')
    errs = np.loadtxt(files.errors)

    if FLAGS.env == 'i':
        color = plt.get_cmap('tab10').colors[0]
    else:
        color = plt.get_cmap('tab10').colors[1]
    if (FLAGS.sens, FLAGS.env) not in done:
        label = 'outdoor' if FLAGS.env == 'o' else 'indoor'
        done.add((FLAGS.sens, FLAGS.env))
    else:
        label = None
    plt.semilogx(sorted(errs), np.arange(len(errs), dtype=float) / len(errs), '.', color=color, ms=0.5, label=label)

    errss.append((flags.sequenceSensorString(), errs))

    p_I_Ps.append((flags.sequenceSensorString(), np.loadtxt(files.p_I_P).ravel()))
示例#6
0
def callback(sequence_i):
    print('%s' % flags.sequenceSensorString())
示例#7
0
def noGtCallback(sequence_i):
    if FLAGS.bag:
        filenames.append(flags.sequenceSensorString() + '.bag')
    if FLAGS.zip:
        filenames.append(flags.sequenceSensorString() + '.zip')
示例#8
0
def gtCallback(sequence_i):
    if FLAGS.bag:
        filenames.append(flags.sequenceSensorString() + '_with_gt.bag')
    if FLAGS.zip:
        filenames.append(flags.sequenceSensorString() + '_with_gt.zip')
示例#9
0
        mRerr = Rerrs.mean()
        print('Mean rotation error is %f degrees' % mRerr)
        mRerrs.append(mRerr)

        plt.figure(d_i)
        for dim, name in enumerate(['x', 'y', 'z']):
            plt.plot(gt_times, [i.t[dim] for i in gt_poses], label=name)
            plt.plot(traj.node_times, [i.t[dim] for i in traj.node_poses],
                     'x',
                     label='%s nodes' % name)
            plt.plot(test_times, [i.t[dim] for i in test_poses],
                     '.',
                     label='%s samples' % name)
        plt.grid()
        # plt.legend()
        plt.title('Disc %.3f s, %s' % (disc, flags.sequenceSensorString()))
        plt.xlabel('t')
        plt.ylabel('position')

    plt.figure(d_i + 1)

    fig, ax1 = plt.subplots()

    color = 'tab:red'
    ax1.set_xlabel('dt = 2^-i')
    ax1.set_ylabel('position error [m]', color=color)
    ax1.semilogy(mterrs, color=color)
    ax1.grid()

    ax2 = ax1.twinx()
示例#10
0
def run():
    print('Getting samples from bag...')
    gt_times, gt_poses, t_GT_spline = evaluate_discretizations.getSamplesFromBag(
    )
    gt_traj = linear_interpolation.Trajectory(gt_times, gt_poses)

    print('Calculating initial guess...')
    traj, valid_times, valid_poses, valid_mask = \
        evaluate_discretizations.considerDiscretization(gt_times, gt_poses, FLAGS.dt)
    valid_gt_poses = [i for i, v in zip(gt_poses, valid_mask) if v]

    print('Formulating symbolic trajectory...')
    sym_traj = bspline_opt.SymbolicTrajectory(traj)

    print('Calculating error terms...')
    want_num_error_terms = FLAGS.errs
    step = (len(valid_times) / want_num_error_terms) + 1
    error_times = valid_times[::step]
    error_gt_poses = valid_gt_poses[::step]

    print('Using %d error times' % len(error_times))

    eRvec = None
    etvec = None
    gtposes = []
    symposes = []
    for t, gtps in zip(error_times, error_gt_poses):
        eR, et, gtp, syp = errorAtTime(gt_traj, sym_traj, t, gt_pose=gtps)
        if eR is not None:
            if eRvec is None:
                eRvec = eR
                etvec = et
            else:
                eRvec = casadi.vertcat(eRvec, eR)
                etvec = casadi.vertcat(etvec, et)
            gtposes.append(gtp)
            symposes.append(syp)

    print('Setting up problem...')
    nlp = {'x': sym_traj.xvec, 'f': casadi.sum1(casadi.vertcat(eRvec, etvec))}
    n_iter = 3
    ipopt_options = {'max_iter': n_iter}
    nlp_options = {'ipopt': ipopt_options, 'verbose': False}
    S = casadi.nlpsol('S', 'ipopt', nlp, nlp_options)

    print('3 iterations at a time...')

    iters = [0]
    print('Old trajectory:')
    mRerr, mterr = numericTrajectoryError(valid_gt_poses, valid_poses)
    mterrs = [mterr]
    mRerrs = [mRerr]

    x0 = np.zeros(sym_traj.xvec.shape)
    xs = [x0]
    for iter in range(10):
        r = S(x0=x0)
        new_traj = sym_traj.newTrajectory(r['x'])
        new_valid_poses = [new_traj.sample(i) for i in valid_times]
        iters.append((iter + 1) * n_iter)
        print('New trajectory, %d iters:' % iters[-1])
        mRerr, mterr = numericTrajectoryError(valid_gt_poses, new_valid_poses)

        mterrs.append(mterr)
        mRerrs.append(mRerr)
        x0 = r['x']
        xs.append(r['x'])

    files = flags.GtFittedSplineFiles()
    if not os.path.exists(files.root):
        os.makedirs(files.root)
    new_traj.serialize(files.spline)
    util.writeRostimeToFile(files.t_GT_spline, t_GT_spline)

    mtns = [maxTwistNorm(x) for x in xs]
    atns = [avgTwistNorm(x) for x in xs]

    # Axis 1: Relative error
    fig, ax1 = plt.subplots()

    color = 'tab:red'
    ax1.set_xlabel('iteration')
    ax1.set_ylabel('Relative error', color=color)
    ax1.semilogy(iters, [i / max(mterrs) for i in mterrs],
                 color=color,
                 label='translation')
    ax1.semilogy(iters, [i / max(mRerrs) for i in mRerrs],
                 '--',
                 color=color,
                 label='rotation')
    ax1.legend()

    ax1.grid()

    ax2 = ax1.twinx()

    color = 'tab:blue'
    ax2.set_ylabel('twist norm (rotation)', color=color)
    ax2.plot(iters, mtns, color=color, label='max')
    ax2.plot(iters, atns, '--', color=color, label='mean')

    ax1.set_title('%s, dt=%.3f, %d nodes, %d t(err)s' %
                  (flags.sequenceSensorString(), FLAGS.dt, len(
                      traj.node_times), len(error_times)))

    fig.tight_layout()  # otherwise the right y-label is slightly clipped

    if FLAGS.gui:
        plt.show()
    else:
        plt.savefig(os.path.join(flags.plotPath(), 'fit_spline_to_gt.pdf'),
                    bbox_inches='tight')
def run():
    alignment = SplineLeicaAlignment()
    alignment.deserialize()
    ground_truth = min_bags.readGroundTruthFromImuGtoBag()
    t_L_Ps, p_L_Ps = leica.parseTextFile(
        os.path.join(flags.rawDataPath(), 'leica.txt'))

    while True:
        aligned_gt = GroundTruthInLeicaFrame(ground_truth, alignment)

        t_L_PGTs = aligned_gt.times()
        t_G0_PGTs = [(i - t_L_PGTs[0]).to_sec() for i in t_L_PGTs]
        t_G0_Ps = [(i - t_L_PGTs[0]).to_sec() for i in t_L_Ps]

        # Calculate errors
        T_L_I_of_t_G0 = aligned_gt.getLinearInterpolation()
        num_errors = numericalErrors(T_L_I_of_t_G0, t_G0_Ps, p_L_Ps,
                                     aligned_gt.alignment.p_I_P)
        print('Mean square error is %f' % np.mean(np.square(num_errors)))

        # Empirically, optimization only made stuff worse after this (?)
        # break

        opti = casadi.Opti()
        t_corr_G0 = opti.variable()
        T_corr_L_twist = opti.variable(6)
        p_I_P = opti.variable(3)
        opti.set_initial(p_I_P, aligned_gt.alignment.p_I_P)

        errvec = symbolicalErrors(T_L_I_of_t_G0, t_G0_Ps, p_L_Ps, p_I_P,
                                  t_corr_G0, T_corr_L_twist)
        opti.minimize(casadi.sum1(errvec))
        opti.solver('ipopt')

        sol = opti.solve()
        upd_coeffs = np.hstack(
            (sol.value(t_corr_G0), sol.value(T_corr_L_twist),
             sol.value(p_I_P) - alignment.p_I_P.ravel()))
        if np.max(np.abs(upd_coeffs)) < 1e-5:
            break

        alignment.t_G_L = alignment.t_G_L + sol.value(t_corr_G0)
        alignment.T_L_G = pose.fromTwist(
            sol.value(T_corr_L_twist)) * alignment.T_L_G
        alignment.p_I_P = sol.value(p_I_P).reshape((3, 1))

    alignment.serialize('gt_leica_alignment')
    out_files = flags.SplineLeicaAlignmentFiles('gt_leica_alignment')
    np.savetxt(out_files.errors, np.array(num_errors))

    if FLAGS.gui:
        plt.figure(0)
        plots.xyPlot(aligned_gt.imuPositions(), aligned_gt.prismPositions(),
                     p_L_Ps)
        plt.title('x,y trajectory of %s' % flags.sequenceSensorString())

        plt.figure(1)
        plots.xyztPlot(t_G0_PGTs, aligned_gt.imuPositions(),
                       aligned_gt.prismPositions(), t_G0_Ps, p_L_Ps)
        plt.title('x,y,z trajectory of %s' % flags.sequenceSensorString())

        plt.figure(2)
        plt.semilogx(sorted(num_errors),
                     np.arange(len(num_errors), dtype=float) / len(num_errors))
        plt.grid()
        plt.xlabel('Leica error [m]')
        plt.ylabel('Fraction of measurements with smaller error')
        plt.title('Cumulative distribution of Leica error for %s' %
                  flags.sequenceSensorString())
        plt.show()