FaramoticsRobot(int argc, char** argv, const Eigen::Vector4s& _laser_1_pose, const Eigen::Vector4s& _laser_2_pose) :
     modelFileName("/home/jvallve/iri-lab/faramotics/models/campusNordUPC.obj"),
     laser_1_pose_(_laser_1_pose),
     laser_2_pose_(_laser_2_pose)
 {
     devicePose.setPose(2, 8, 0.2, 0, 0, 0);
     viewPoint.setPose(devicePose);
     viewPoint.moveForward(10);
     viewPoint.rt.setEuler(viewPoint.rt.head() + M_PI / 2, viewPoint.rt.pitch() + 30. * M_PI / 180., viewPoint.rt.roll());
     viewPoint.moveForward(-15);
     //glut initialization
     faramotics::initGLUT(argc, argv);
     //create a viewer for the 3D model and scan points
     myRender = new CdynamicSceneRender(1200, 700, 90 * M_PI / 180, 90 * 700.0 * M_PI / (1200.0 * 180.0), 0.2, 100);
     myRender->loadAssimpModel(modelFileName, true); //with wireframe
     //create scanner and load 3D model
     myScanner = new CrangeScan2D(HOKUYO_UTM30LX_180DEG);  //HOKUYO_UTM30LX_180DEG or LEUZE_RS4
     myScanner->loadAssimpModel(modelFileName);
 }
예제 #2
0
//main
int main(int argc, char *argv[])
{
    using namespace Eigen;
    using namespace wolf;

    // USER INPUT ============================================================================================
    if (argc != 3 || atoi(argv[1]) < 1 || atoi(argv[1]) > 1100 || atoi(argv[2]) < 0 || atoi(argv[2]) > 2)
    {
        std::cout << "Please call me with: [./test_ceres_manager NI MODE], where:" << std::endl;
        std::cout << "     - NI is the number of iterations (0 < NI < 1100)" << std::endl;
        std::cout << "     - MODE is the solver mode (0 batch (no ordering), 1 batch (ordering), 2 incremental" << std::endl;
        std::cout << "EXIT due to bad user input" << std::endl << std::endl;
        return -1;
    }
    bool complex_angle = false;
    unsigned int solving_mode = (unsigned int) atoi(argv[2]); //solving mode
    unsigned int n_execution = (unsigned int) atoi(argv[1]); //number of iterations of the whole execution

    // INITIALIZATION ============================================================================================


    //init random generators
    Scalar odom_std_factor = 0.1;
    Scalar gps_std = 10;
    std::default_random_engine generator(1);
    std::normal_distribution<Scalar> gaussian_distribution(0.0, 1);

    // Faramotics stuff
    Cpose3d viewPoint, devicePose, laser1Pose, laser2Pose, estimated_vehicle_pose, estimated_laser_1_pose, estimated_laser_2_pose;
    vector < Cpose3d > devicePoses;
    vector<float> scan1, scan2;
    string modelFileName;

    //model and initial view point
    modelFileName = "/home/jvallve/iri-lab/faramotics/models/campusNordUPC.obj";
    //modelFileName = "/home/acoromin/dev/br/faramotics/models/campusNordUPC.obj";
    //modelFileName = "/home/andreu/dev/faramotics/models/campusNordUPC.obj";
    devicePose.setPose(2, 8, 0.2, 0, 0, 0);
    viewPoint.setPose(devicePose);
    viewPoint.moveForward(10);
    viewPoint.rt.setEuler(viewPoint.rt.head() + M_PI / 2, viewPoint.rt.pitch() + 30. * M_PI / 180., viewPoint.rt.roll());
    viewPoint.moveForward(-15);
    //glut initialization
    faramotics::initGLUT(argc, argv);

    //create a viewer for the 3D model and scan points
    CdynamicSceneRender* myRender = new CdynamicSceneRender(1200, 700, 90 * M_PI / 180, 90 * 700.0 * M_PI / (1200.0 * 180.0), 0.2, 100);
    myRender->loadAssimpModel(modelFileName, true); //with wireframe
    //create scanner and load 3D model
    CrangeScan2D* myScanner = new CrangeScan2D(HOKUYO_UTM30LX_180DEG);  //HOKUYO_UTM30LX_180DEG or LEUZE_RS4
    myScanner->loadAssimpModel(modelFileName);

    //variables
    Eigen::Vector3s odom_reading;
    Eigen::Vector2s gps_fix_reading;
    Eigen::VectorXs pose_odom(3); //current odometry integred pose
    Eigen::VectorXs ground_truth(n_execution * 3); //all true poses
    Eigen::VectorXs odom_trajectory(n_execution * 3); //open loop trajectory
    Eigen::VectorXs mean_times = Eigen::VectorXs::Zero(7);
    clock_t t1, t2;

    // Wolf manager initialization
    Eigen::Vector3s odom_pose = Eigen::Vector3s::Zero();
    Eigen::Vector3s gps_pose = Eigen::Vector3s::Zero();
    Eigen::Vector4s laser_1_pose, laser_2_pose; //xyz + theta
    laser_1_pose << 1.2, 0, 0, 0; //laser 1
    laser_2_pose << -1.2, 0, 0, M_PI; //laser 2
    SensorOdom2D odom_sensor(new StateBlock(odom_pose.head(2)), new StateBlock(odom_pose.tail(1)), odom_std_factor, odom_std_factor);
    SensorGPSFix gps_sensor(new StateBlock(gps_pose.head(2)), new StateBlock(gps_pose.tail(1)), gps_std);
    SensorLaser2D laser_1_sensor(new StateBlock(laser_1_pose.head(2)), new StateBlock(laser_1_pose.tail(1)), laserscanutils::LaserScanParams({M_PI/2,-M_PI/2, -M_PI/720,0.01,0.2,100,0.01,0.01}));
    SensorLaser2D laser_2_sensor(new StateBlock(laser_2_pose.head(2)), new StateBlock(laser_2_pose.tail(1)), laserscanutils::LaserScanParams({M_PI/2,-M_PI/2, -M_PI/720,0.01,0.2,100,0.01,0.01}));

    // Initial pose
    pose_odom << 2, 8, 0;
    ground_truth.head(3) = pose_odom;
    odom_trajectory.head(3) = pose_odom;

    WolfManager* wolf_manager_QR = new WolfManager(FRM_PO_2D, &odom_sensor, pose_odom, Eigen::Matrix3s::Identity() * 0.01, n_execution*10, 0.01);
    WolfManager* wolf_manager_ceres = new WolfManager(FRM_PO_2D, &odom_sensor, pose_odom, Eigen::Matrix3s::Identity() * 0.01, n_execution*10, 0.01);

    // Ceres initialization
    ceres::Solver::Options ceres_options;
    ceres_options.minimizer_type = ceres::TRUST_REGION; //ceres::TRUST_REGION;LINE_SEARCH
    ceres_options.max_line_search_step_contraction = 1e-3;
    //    ceres_options.minimizer_progress_to_stdout = false;
    //    ceres_options.line_search_direction_type = ceres::LBFGS;
    //    ceres_options.max_num_iterations = 100;
    CeresManager* ceres_manager = new CeresManager(wolf_manager_ceres->getProblemPtr(), ceres_options);
    std::ofstream log_file, landmark_file;  //output file

    // Own solver
    SolverQR solver_(wolf_manager_QR->getProblemPtr());

    std::cout << "STARTING INCREMENTAL QR TEST" << std::endl << std::endl;
    std::cout << "\n ========= 2D Robot with odometry and 2 LIDARs ===========\n";
    // START TRAJECTORY ============================================================================================
    for (unsigned int step = 1; step < n_execution; step++)
    {
        //get init time
        t2 = clock();

        // ROBOT MOVEMENT ---------------------------
        //std::cout << "ROBOT MOVEMENT..." << std::endl;
        // moves the device position
        t1 = clock();
        motionCampus(step, devicePose, odom_reading(0), odom_reading(2));
        odom_reading(1) = 0;
        devicePoses.push_back(devicePose);

        // SENSOR DATA ---------------------------
        //std::cout << "SENSOR DATA..." << std::endl;
        // store groundtruth
        ground_truth.segment(step * 3, 3) << devicePose.pt(0), devicePose.pt(1), devicePose.rt.head();

        // compute odometry
        odom_reading(0) += gaussian_distribution(generator) * odom_std_factor * (odom_reading(0) == 0 ? 1e-6 : odom_reading(0));
        odom_reading(1) += gaussian_distribution(generator) * odom_std_factor * 1e-6;
        odom_reading(2) += gaussian_distribution(generator) * odom_std_factor * (odom_reading(2) == 0 ? 1e-6 : odom_reading(2));

        // odometry integration
        pose_odom(0) = pose_odom(0) + odom_reading(0) * cos(pose_odom(2)) - odom_reading(1) * sin(pose_odom(2));
        pose_odom(1) = pose_odom(1) + odom_reading(0) * sin(pose_odom(2)) + odom_reading(1) * cos(pose_odom(2));
        pose_odom(2) = pose_odom(2) + odom_reading(1);
        odom_trajectory.segment(step * 3, 3) = pose_odom;

        // compute GPS
        gps_fix_reading << devicePose.pt(0), devicePose.pt(1);
        gps_fix_reading(0) += gaussian_distribution(generator) * gps_std;
        gps_fix_reading(1) += gaussian_distribution(generator) * gps_std;

        //compute scans
        scan1.clear();
        scan2.clear();
        // scan 1
        laser1Pose.setPose(devicePose);
        laser1Pose.moveForward(laser_1_pose(0));
        myScanner->computeScan(laser1Pose, scan1);
        // scan 2
        laser2Pose.setPose(devicePose);
        laser2Pose.moveForward(laser_2_pose(0));
        laser2Pose.rt.setEuler(laser2Pose.rt.head() + M_PI, laser2Pose.rt.pitch(), laser2Pose.rt.roll());
        myScanner->computeScan(laser2Pose, scan2);

        mean_times(0) += ((double) clock() - t1) / CLOCKS_PER_SEC;

        // ADD CAPTURES ---------------------------
        //std::cout << "ADD CAPTURES..." << std::endl;
        // adding new sensor captures
        wolf_manager_QR->addCapture(new CaptureOdom2D(TimeStamp(), TimeStamp(), &odom_sensor, odom_reading));       //, odom_std_factor * Eigen::MatrixXs::Identity(2,2)));
        wolf_manager_QR->addCapture(new CaptureGPSFix(TimeStamp(), &gps_sensor, gps_fix_reading, gps_std * gps_std * Eigen::MatrixXs::Identity(3,3)));
        wolf_manager_ceres->addCapture(new CaptureOdom2D(TimeStamp(), TimeStamp(), &odom_sensor, odom_reading));       //, odom_std_factor * Eigen::MatrixXs::Identity(2,2)));
        wolf_manager_ceres->addCapture(new CaptureGPSFix(TimeStamp(), &gps_sensor, gps_fix_reading, gps_std * gps_std * Eigen::MatrixXs::Identity(3,3)));
        //wolf_manager->addCapture(new CaptureLaser2D(TimeStamp(), &laser_1_sensor, scan1));
        //wolf_manager->addCapture(new CaptureLaser2D(TimeStamp(), &laser_2_sensor, scan2));
        // updating problem
        wolf_manager_QR->update();
        wolf_manager_ceres->update();

        // UPDATING SOLVER ---------------------------
        //std::cout << "UPDATING..." << std::endl;
        // update state units and constraints in ceres
        solver_.update();

        // PRINT PROBLEM
        //solver_.printProblem();

        // SOLVE OPTIMIZATION ---------------------------
        //std::cout << "SOLVING..." << std::endl;
        ceres::Solver::Summary summary = ceres_manager->solve();
        solver_.solve(solving_mode);

        std::cout << "========================= RESULTS " << step << ":" << std::endl;
        //solver_.printResults();
        std::cout << "QR vehicle pose    " << wolf_manager_QR->getVehiclePose().transpose() << std::endl;
        std::cout << "ceres vehicle pose " << wolf_manager_ceres->getVehiclePose().transpose() << std::endl;

        // COMPUTE COVARIANCES ---------------------------
        //std::cout << "COMPUTING COVARIANCES..." << std::endl;
        // TODO

        // DRAWING STUFF ---------------------------
        // draw detected corners
//        std::list < laserscanutils::Corner > corner_list;
//        std::vector<double> corner_vector;
//        CaptureLaser2D last_scan(TimeStamp(), &laser_1_sensor, scan1);
//        last_scan.extractCorners(corner_list);
//        for (std::list<laserscanutils::Corner>::iterator corner_it = corner_list.begin(); corner_it != corner_list.end(); corner_it++)
//        {
//            corner_vector.push_back(corner_it->pt_(0));
//            corner_vector.push_back(corner_it->pt_(1));
//        }
//        myRender->drawCorners(laser1Pose, corner_vector);

        // draw landmarks
        std::vector<double> landmark_vector;
        for (auto landmark_it = wolf_manager_QR->getProblemPtr()->getMapPtr()->getLandmarkListPtr()->begin(); landmark_it != wolf_manager_QR->getProblemPtr()->getMapPtr()->getLandmarkListPtr()->end(); landmark_it++)
        {
            Scalar* position_ptr = (*landmark_it)->getPPtr()->getPtr();
            landmark_vector.push_back(*position_ptr); //x
            landmark_vector.push_back(*(position_ptr + 1)); //y
            landmark_vector.push_back(0.2); //z
        }
        myRender->drawLandmarks(landmark_vector);

        // draw localization and sensors
        estimated_vehicle_pose.setPose(wolf_manager_QR->getVehiclePose()(0), wolf_manager_QR->getVehiclePose()(1), 0.2, wolf_manager_QR->getVehiclePose()(2), 0, 0);
        estimated_laser_1_pose.setPose(estimated_vehicle_pose);
        estimated_laser_1_pose.moveForward(laser_1_pose(0));
        estimated_laser_2_pose.setPose(estimated_vehicle_pose);
        // instead of laser 2 we draw ceres solution
        //estimated_laser_2_pose.moveForward(laser_2_pose(0));
        //estimated_laser_2_pose.rt.setEuler(estimated_laser_2_pose.rt.head() + M_PI, estimated_laser_2_pose.rt.pitch(), estimated_laser_2_pose.rt.roll());
        estimated_laser_2_pose.setPose(wolf_manager_ceres->getVehiclePose()(0), wolf_manager_ceres->getVehiclePose()(1), 0.2, wolf_manager_ceres->getVehiclePose()(2), 0, 0);

        myRender->drawPoseAxisVector( { estimated_vehicle_pose, estimated_laser_1_pose, estimated_laser_2_pose });

        //Set view point and render the scene
        //locate visualization view point, somewhere behind the device
        myRender->setViewPoint(viewPoint);
        myRender->drawPoseAxis(devicePose);
        myRender->drawScan(laser1Pose, scan1, 180. * M_PI / 180., 90. * M_PI / 180.); //draw scan
        myRender->render();

        // TIME MANAGEMENT ---------------------------
        double dt = ((double) clock() - t2) / CLOCKS_PER_SEC;
        mean_times(6) += dt;
        if (dt < 0.1)
            usleep(100000 - 1e6 * dt);

//      std::cout << "\nTree after step..." << std::endl;
//      wolf_manager->getProblemPtr()->print();
    }

    // DISPLAY RESULTS ============================================================================================
    mean_times /= n_execution;
    std::cout << "\nSIMULATION AVERAGE LOOP DURATION [s]" << std::endl;
    std::cout << "  data generation:    " << mean_times(0) << std::endl;
    std::cout << "  wolf managing:      " << mean_times(1) << std::endl;
    std::cout << "  ceres managing:     " << mean_times(2) << std::endl;
    std::cout << "  ceres optimization: " << mean_times(3) << std::endl;
    std::cout << "  ceres covariance:   " << mean_times(4) << std::endl;
    std::cout << "  results drawing:    " << mean_times(5) << std::endl;
    std::cout << "  loop time:          " << mean_times(6) << std::endl;

//  std::cout << "\nTree before deleting..." << std::endl;
//  wolf_manager->getProblemPtr()->print();

    // Draw Final result -------------------------
    std::cout << "Drawing final results..." << std::endl;
    std::vector<double> landmark_vector;
    for (auto landmark_it = wolf_manager_QR->getProblemPtr()->getMapPtr()->getLandmarkListPtr()->begin(); landmark_it != wolf_manager_QR->getProblemPtr()->getMapPtr()->getLandmarkListPtr()->end(); landmark_it++)
    {
        Scalar* position_ptr = (*landmark_it)->getPPtr()->getPtr();
        landmark_vector.push_back(*position_ptr); //x
        landmark_vector.push_back(*(position_ptr + 1)); //y
        landmark_vector.push_back(0.2); //z
    }
    myRender->drawLandmarks(landmark_vector);
//  viewPoint.setPose(devicePoses.front());
//  viewPoint.moveForward(10);
//  viewPoint.rt.setEuler( viewPoint.rt.head()+M_PI/4, viewPoint.rt.pitch()+20.*M_PI/180., viewPoint.rt.roll() );
//  viewPoint.moveForward(-10);
    myRender->setViewPoint(viewPoint);
    myRender->render();

    // Print Final result in a file -------------------------
    std::cout << "Printing results in a file..." << std::endl;
    // Vehicle poses
    std::cout << "Vehicle poses..." << std::endl;
    int i = 0;
    Eigen::VectorXs state_poses(wolf_manager_QR->getProblemPtr()->getTrajectoryPtr()->getFrameListPtr()->size() * 3);
    for (auto frame_it = wolf_manager_QR->getProblemPtr()->getTrajectoryPtr()->getFrameListPtr()->begin(); frame_it != wolf_manager_QR->getProblemPtr()->getTrajectoryPtr()->getFrameListPtr()->end(); frame_it++)
    {
        if (complex_angle)
            state_poses.segment(i, 3) << *(*frame_it)->getPPtr()->getPtr(), *((*frame_it)->getPPtr()->getPtr() + 1), atan2(*(*frame_it)->getOPtr()->getPtr(), *((*frame_it)->getOPtr()->getPtr() + 1));
        else
            state_poses.segment(i, 3) << *(*frame_it)->getPPtr()->getPtr(), *((*frame_it)->getPPtr()->getPtr() + 1), *(*frame_it)->getOPtr()->getPtr();
        i += 3;
    }

    // Landmarks
    std::cout << "Landmarks..." << std::endl;
    i = 0;
    Eigen::VectorXs landmarks(wolf_manager_QR->getProblemPtr()->getMapPtr()->getLandmarkListPtr()->size() * 2);
    for (auto landmark_it = wolf_manager_QR->getProblemPtr()->getMapPtr()->getLandmarkListPtr()->begin(); landmark_it != wolf_manager_QR->getProblemPtr()->getMapPtr()->getLandmarkListPtr()->end(); landmark_it++)
    {
        Eigen::Map<Eigen::Vector2s> landmark((*landmark_it)->getPPtr()->getPtr());
        landmarks.segment(i, 2) = landmark;
        i += 2;
    }

    // Print log files
    std::string filepath = getenv("HOME") + (complex_angle ? std::string("/Desktop/log_file_3.txt") : std::string("/Desktop/log_file_2.txt"));
    log_file.open(filepath, std::ofstream::out); //open log file

    if (log_file.is_open())
    {
        log_file << 0 << std::endl;
        for (unsigned int ii = 0; ii < n_execution; ii++)
            log_file << state_poses.segment(ii * 3, 3).transpose() << "\t" << ground_truth.segment(ii * 3, 3).transpose() << "\t" << (state_poses.segment(ii * 3, 3) - ground_truth.segment(ii * 3, 3)).transpose() << "\t" << odom_trajectory.segment(ii * 3, 3).transpose() << std::endl;
        log_file.close(); //close log file
        std::cout << std::endl << "Result file " << filepath << std::endl;
    }
    else
        std::cout << std::endl << "Failed to write the log file " << filepath << std::endl;

    std::string filepath2 = getenv("HOME") + (complex_angle ? std::string("/Desktop/landmarks_file_3.txt") : std::string("/Desktop/landmarks_file_2.txt"));
    landmark_file.open(filepath2, std::ofstream::out); //open log file

    if (landmark_file.is_open())
    {
        for (unsigned int ii = 0; ii < landmarks.size(); ii += 2)
            landmark_file << landmarks.segment(ii, 2).transpose() << std::endl;
        landmark_file.close(); //close log file
        std::cout << std::endl << "Landmark file " << filepath << std::endl;
    }
    else
        std::cout << std::endl << "Failed to write the landmark file " << filepath << std::endl;

    std::cout << "Press any key for ending... " << std::endl << std::endl;
    std::getchar();

    delete myRender;
    delete myScanner;
    delete wolf_manager_QR;
    delete wolf_manager_ceres;
    std::cout << "wolf deleted" << std::endl;

    std::cout << " ========= END ===========" << std::endl << std::endl;

    //exit
    return 0;
}