Example #1
0
int planandnavigate3dkin(int argc, char *argv[])
{

	double allocated_time_secs_foreachplan = 2.0; //in seconds
	MDPConfig MDPCfg;
	EnvironmentNAV3DKIN environment_nav3Dkin;
	EnvironmentNAV3DKIN trueenvironment_nav3Dkin;
    int size_x=-1,size_y=-1;
    double startx = 0, starty = 0, starttheta = 0;
    double goalx=-1, goaly=-1, goaltheta = -1;
	double goaltol_x = 0.1, goaltol_y = 0.1, goaltol_theta = 0.1;
    FILE* fSol = fopen("sol.txt", "w");
    //int dx[8] = {-1, -1, -1,  0,  0,  1,  1,  1};
    //int dy[8] = {-1,  0,  1, -1,  1, -1,  0,  1};
	bool bPrint = false, bPrintMap = false;
	int x,y;
	vector<int> preds_of_changededgesIDV;
	vector<nav2dcell_t> changedcellsV;
	nav2dcell_t nav2dcell;
	int i;
	double cellsize_m, nominalvel_mpersecs, timetoturn45degsinplace_secs;
	vector<sbpl_2Dpt_t> perimeterptsV;
	bool bsearchuntilfirstsolution = false; 
	unsigned char obsthresh = 0;


	//srand(0);

    //initialize true map and robot map
	if(!trueenvironment_nav3Dkin.InitializeEnv(argv[1]))
	{
		printf("ERROR: InitializeEnv failed\n");
		exit(1);
	}
	trueenvironment_nav3Dkin.GetEnvParms(&size_x, &size_y, &startx, &starty, &starttheta, &goalx, &goaly, &goaltheta, &cellsize_m, 
		&nominalvel_mpersecs, &timetoturn45degsinplace_secs, &obsthresh);

    unsigned char* map = (unsigned char*)calloc(size_x*size_y, sizeof(unsigned char));

	//print the map
	if(bPrintMap) printf("true map:\n");
	for(y = 0; bPrintMap && y < size_y; y++){
		for(x = 0; x < size_x; x++){
			printf("%3d ", trueenvironment_nav3Dkin.GetMapCost(x,y));
		}
		printf("\n");
	}
	if(bPrint) system("pause");

	printf("start: %f %f %f, goal: %f %f %f\n", startx, starty, starttheta, goalx, goaly, goaltheta);

	//set the perimeter of the robot (it is given with 0,0,0 robot ref. point for which planning is done)
	sbpl_2Dpt_t pt_m;
	double side = 0.6;
	pt_m.x = -side;
	pt_m.y = -side;
	perimeterptsV.push_back(pt_m);
	pt_m.x = side;
	pt_m.y = -side;
	perimeterptsV.push_back(pt_m);
	pt_m.x = side;
	pt_m.y = side;
	perimeterptsV.push_back(pt_m);
	pt_m.x = -side;
	pt_m.y = side;
	perimeterptsV.push_back(pt_m);


	//compute sensing
	double maxx = 0;
	double maxy = 0;
	for(i = 0; i < (int)perimeterptsV.size(); i++)
	{
		if(maxx < fabs(perimeterptsV.at(i).x))
			maxx = fabs(perimeterptsV.at(i).x);
		if(maxy < fabs(perimeterptsV.at(i).y))
			maxy = fabs(perimeterptsV.at(i).y);
	}
	int sensingrange_c = (int)(__max(maxx, maxy)/cellsize_m) + 2;
	printf("sensing range=%d cells\n", sensingrange_c);
	vector<sbpl_2Dcell_t> sensecells;
	for(i = -sensingrange_c; i <= sensingrange_c; i++)
	{
		sbpl_2Dcell_t sensecell;

		sensecell.x = i;
		sensecell.y = sensingrange_c;
		sensecells.push_back(sensecell);
		sensecell.x = i;
		sensecell.y = -sensingrange_c;
		sensecells.push_back(sensecell);
		sensecell.x = sensingrange_c;
		sensecell.y = i;
		sensecells.push_back(sensecell);
		sensecell.x = -sensingrange_c;
		sensecell.y = i;
		sensecells.push_back(sensecell);
	}


	//Initialize Environment (should be called before initializing anything else)
	
    if(!environment_nav3Dkin.InitializeEnv(size_x, size_y, map, 0,0,0,0,0,0, 
		goaltol_x, goaltol_y, goaltol_theta, perimeterptsV,
		cellsize_m, nominalvel_mpersecs, timetoturn45degsinplace_secs, 
		obsthresh)){
		printf("ERROR: InitializeEnv failed\n");
		exit(1);
	}

	/*	
    if(!environment_nav3Dkin.InitializeEnv(size_x, size_y, map, startx, starty, starttheta, goalx, goaly, goaltheta, 
		goaltol_x, goaltol_y, goaltol_theta, perimeterptsV,
		cellsize_m, nominalvel_mpersecs, timetoturn45degsinplace_secs, 
		obsthresh)){
		printf("ERROR: InitializeEnv failed\n");
		exit(1);
	}
	*/
	environment_nav3Dkin.SetStart(startx, starty,starttheta);

	//Initialize MDP Info
	if(!environment_nav3Dkin.InitializeMDPCfg(&MDPCfg))
	{
		printf("ERROR: InitializeMDPCfg failed\n");
		exit(1);
	}


	//create a planner
	vector<int> solution_stateIDs_V;
	bool bforwardsearch = false;
    //ARAPlanner planner(&environment_nav3Dkin, bforwardsearch);
	ADPlanner planner(&environment_nav3Dkin, bforwardsearch);

	planner.set_initialsolution_eps(5.0); 

	//set search mode
	planner.set_search_mode(bsearchuntilfirstsolution);

    //set the start and goal configurations
    if(planner.set_start(MDPCfg.startstateid) == 0)
        {
            printf("ERROR: failed to set start state\n");
            exit(1);
        }


	MDPCfg.goalstateid = environment_nav3Dkin.SetGoal(goalx, goaly, goaltheta);


    if(planner.set_goal(MDPCfg.goalstateid) == 0)
        {
            printf("ERROR: failed to set goal state\n");
            exit(1);
        }

    //now comes the main loop
	int goalx_c = CONTXY2DISC(goalx, cellsize_m);
	int goaly_c = CONTXY2DISC(goaly, cellsize_m);
	int goaltheta_c = ContTheta2Disc(goaltheta, NAV3DKIN_THETADIRS);
	printf("goal_c: %d %d %d\n", goalx_c, goaly_c, goaltheta_c);
    while(fabs(startx - goalx) > goaltol_x || fabs(starty - goaly) > goaltol_y || fabs(starttheta - goaltheta) > goaltol_theta){

        //simulate sensor data update
        bool bChanges = false;
		preds_of_changededgesIDV.clear();
		changedcellsV.clear();
        for(i = 0; i < (int)sensecells.size(); i++){
            int x = CONTXY2DISC(startx,cellsize_m) + sensecells.at(i).x;
            int y = CONTXY2DISC(starty,cellsize_m) + sensecells.at(i).y;
            if(x < 0 || x >= size_x || y < 0 || y >= size_y)
                continue;
            int index = x + y*size_x;
			unsigned char truecost = trueenvironment_nav3Dkin.GetMapCost(x,y);
            if(map[index] != truecost){
                map[index] = truecost;
                environment_nav3Dkin.UpdateCost(x,y,map[index]);
                printf("setting cost[%d][%d] to %d\n", x,y,map[index]);
                bChanges = true;
				//store the changed cells
				nav2dcell.x = x;
				nav2dcell.y = y;
				changedcellsV.push_back(nav2dcell);
            }
        }

		double TimeStarted = clock();

        if(bChanges){
            //planner.costs_changed(); //use by ARA* planner (non-incremental)

			//get the affected states
			environment_nav3Dkin.GetPredsofChangedEdges(&changedcellsV, &preds_of_changededgesIDV);
			//let know the incremental planner about them
			planner.update_preds_of_changededges(&preds_of_changededgesIDV); //use by AD* planner (incremental)
			//printf("%d states were affected\n", preds_of_changededgesIDV.size());

        }

		int startx_c = CONTXY2DISC(startx,cellsize_m);
		int starty_c = CONTXY2DISC(starty,cellsize_m);
		int starttheta_c = ContTheta2Disc(starttheta, NAV3DKIN_THETADIRS);
		

        fprintf(fSol, "%d %d %d ",  startx_c, starty_c, starttheta_c);

        //plan a path 
        bool bPlanExists = false;

		printf("new planning...\n");   
        bPlanExists = (planner.replan(allocated_time_secs_foreachplan, &solution_stateIDs_V) == 1);
        printf("done with the solution of size=%d and sol. eps=%f\n", solution_stateIDs_V.size(), planner.get_solution_eps());   
        environment_nav3Dkin.PrintTimeStat(stdout);

		fprintf(fSol, "%.5f %.2f\n", (clock()-TimeStarted)/((double)CLOCKS_PER_SEC), planner.get_solution_eps());
		fflush(fSol);

        //for(unsigned int i = 0; i < solution_stateIDs_V.size(); i++) {
        //environment_nav3Dkin.PrintState(solution_stateIDs_V[i], true, fSol);
        //}
        //fprintf(fSol, "*********\n");

		//print the map
		int startindex = startx_c + starty_c*size_x;
		int goalindex = goalx_c + goaly_c*size_x;
		for(y = 0; bPrintMap && y < size_y; y++){
			for(x = 0; x < size_x; x++){
				int index = x + y*size_x;

				//check to see if it is on the path
				bool bOnthePath = false;
				for(int j = 1; j < (int)solution_stateIDs_V.size(); j++)
				{
					int newx, newy, newtheta=0;
					environment_nav3Dkin.GetCoordFromState(solution_stateIDs_V[j], newx, newy, newtheta); 
					if(x == newx && y == newy)
						bOnthePath = true;
				}

				if (index != startindex && index != goalindex && !bOnthePath)
					printf("%3d ", map[index]);
				else if(index == startindex)
					printf("  X ");
				else if(index == goalindex)
					printf("  G ");
				else if (bOnthePath)
					printf("  * ");
				else
					printf("? ");
			}
			printf("\n");
		}


        //move along the path
        if(bPlanExists && (int)solution_stateIDs_V.size() > 1){
            //get coord of the successor
            int newx, newy, newtheta;
            environment_nav3Dkin.GetCoordFromState(solution_stateIDs_V[1], newx, newy, newtheta);

            printf("moving from %d %d %d to %d %d %d\n", startx_c, starty_c, starttheta_c, newx, newy, newtheta);
 

			//this check is weak since true configuration does not know the actual perimeter of the robot
			if(!trueenvironment_nav3Dkin.IsValidConfiguration(newx,newy,newtheta)) 
			{
				printf("ERROR: robot is commanded to move into an invalid configuration\n");
				exit(1);
			}
			if(!environment_nav3Dkin.IsValidConfiguration(newx,newy,newtheta))
			{
				printf("ERROR: robot is commanded to move into an invalid configuration\n");
				exit(1);
			}

            //move
            startx = DISCXY2CONT(newx, cellsize_m);
            starty = DISCXY2CONT(newy, cellsize_m);
			starttheta = DiscTheta2Cont(newtheta, NAV3DKIN_THETADIRS);
			
            //update the environment
            environment_nav3Dkin.SetStart(startx, starty,starttheta);

            //update the planner
            if(planner.set_start(solution_stateIDs_V[1]) == 0){               
                printf("ERROR: failed to update robot pose in the planner\n");
                exit(1);
            }
        }
		else
		{
			printf("No move is made\n");
		}

		if(bPrint) system("pause");


    }

	printf("goal reached!\n");

	fflush(NULL);


    return 1;
}
bool PlanningEnvironmentMPH::readinMotionPrimitive(SBPL_xytheta_mprimitive* pMotPrim, FILE* fIn, double resolutionCorrectionFactor)
{
    char sTemp[1024];
    int dTemp;
    char sExpected[1024];
    int numofIntermPoses;

    //read in actionID
    strcpy(sExpected, "primID:");
    if (fscanf(fIn, "%s", sTemp) == 0)
        return false;
    if (strcmp(sTemp, sExpected) != 0)
    {
        SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
        return false;
    }
    if (fscanf(fIn, "%d", &pMotPrim->motprimID) != 1)
        return false;

    //read in start angle
    strcpy(sExpected, "startangle_c:");
    if (fscanf(fIn, "%s", sTemp) == 0)
        return false;
    if (strcmp(sTemp, sExpected) != 0)
    {
        SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
        return false;
    }
    if (fscanf(fIn, "%d", &dTemp) == 0)
    {
        SBPL_ERROR("ERROR reading start angle\n");
        return false;
    }
    pMotPrim->starttheta_c = dTemp;

    //read in end pose
    strcpy(sExpected, "endpose_c:");
    if (fscanf(fIn, "%s", sTemp) == 0)
        return false;
    if (strcmp(sTemp, sExpected) != 0)
    {
        SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
        return false;
    }

    if (readinCell(&pMotPrim->endcell, fIn) == false)
    {
        SBPL_ERROR("ERROR: failed to read in end search pose\n");
        return false;
    }

    //read in action cost
    strcpy(sExpected, "additionalactioncostmult:");
    if (fscanf(fIn, "%s", sTemp) == 0)
        return false;
    if (strcmp(sTemp, sExpected) != 0)
    {
        SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
        return false;
    }
    if (fscanf(fIn, "%d", &dTemp) != 1)
        return false;
    pMotPrim->additionalactioncostmult = dTemp;

    //read in intermediate poses
    strcpy(sExpected, "intermediateposes:");
    if (fscanf(fIn, "%s", sTemp) == 0)
        return false;
    if (strcmp(sTemp, sExpected) != 0)
    {
        SBPL_ERROR("ERROR: expected %s but got %s\n", sExpected, sTemp);
        return false;
    }
    if (fscanf(fIn, "%d", &numofIntermPoses) != 1)
        return false;
    //all intermposes should be with respect to 0,0 as starting pose since it will be added later and should be done
    //after the action is rotated by initial orientation
    for (int i = 0; i < numofIntermPoses; i++)
    {
        sbpl_xy_theta_pt_t intermpose;
        if (readinPose(&intermpose, fIn, resolutionCorrectionFactor) == false)
        {
            SBPL_ERROR("ERROR: failed to read in intermediate poses\n");
            return false;
        }
        pMotPrim->intermptV.push_back(intermpose);
    }

    //check that the last pose corresponds correctly to the last pose
    pMotPrim->endcell.x *= params::motionPrimitiveScaleFactor;
    pMotPrim->endcell.y *= params::motionPrimitiveScaleFactor;
    sbpl_xy_theta_pt_t sourcepose;
    sourcepose.x = DISCXY2CONT(0, params::motionPrimitiveResolution);
    sourcepose.y = DISCXY2CONT(0, params::motionPrimitiveResolution);
    sourcepose.theta = DiscTheta2Cont(pMotPrim->starttheta_c, State::cellSize.yaw_count);
    double mp_endx_m = sourcepose.x + pMotPrim->intermptV[pMotPrim->intermptV.size() - 1].x;
    double mp_endy_m = sourcepose.y + pMotPrim->intermptV[pMotPrim->intermptV.size() - 1].y;
    double mp_endtheta_rad = pMotPrim->intermptV[pMotPrim->intermptV.size() - 1].theta;
    int endx_c = CONTXY2DISC(mp_endx_m, params::motionPrimitiveResolution);
    int endy_c = CONTXY2DISC(mp_endy_m, params::motionPrimitiveResolution);
    int endtheta_c = ContTheta2Disc(mp_endtheta_rad, State::cellSize.yaw_count);
//    sbpl_xy_theta_pt_t& pose = pMotPrim->intermptV.back();
//    ROS_INFO("mp: [%0.3f %0.3f %0.3f] [%d %d %d]", pose.x, pose.y, pose.theta, pMotPrim->endcell.x, pMotPrim->endcell.y, pMotPrim->endcell.theta);
    if (endx_c != pMotPrim->endcell.x || endy_c != pMotPrim->endcell.y || endtheta_c != pMotPrim->endcell.theta)
    {
        SBPL_ERROR("ERROR: incorrect primitive %d with startangle=%d last interm point %f %f %f does not match end pose %d %d %d\n", pMotPrim->motprimID, pMotPrim->starttheta_c, pMotPrim->intermptV[pMotPrim->intermptV.size() - 1].x, pMotPrim->intermptV[pMotPrim->intermptV.size() - 1].y,
                pMotPrim->intermptV[pMotPrim->intermptV.size() - 1].theta, pMotPrim->endcell.x, pMotPrim->endcell.y, pMotPrim->endcell.theta);
        return false;
    }
    pMotPrim->endcell.x /= params::motionPrimitiveScaleFactor;
    pMotPrim->endcell.y /= params::motionPrimitiveScaleFactor;

    return true;
}