Esempio n. 1
0
void Visualizer::Run(){
        //std::cout << animationStatus << "...";

        switch(animationStatus) {
        case 0: clear(); break;
        case 1: stroboscope(); break;
        case 2: lightchange(); break;
        case 3: fadeIn(); break;
        case 4: pulseCircle(); break;
        case 5: lines(); break;
        case 6: circles(); break;
        case 7: randomLines(); break;
        case 8: square(); break;
        case 9: randomPixel(); break;
        case 10: rotateLine(); break;
        }
        return;

}
/**
 * Combine the lines extracted from segments into a single set of lines which
 * hopefully represent the walls in the maze. The first segment starts at 0,0
 * and other segments need to be rotated to correspond to the relative rotation
 * of the segment that precedes them, based on the turn made by the robot. Just
 * rotating the points that correspond to the line start and end and then
 * rotating around the point that ends the previous segment should work?
 * Transform the point we are rotating around to the origin, rotate the points,
 * then translate back.
 *
 * Should return the lines for the segments rotated and translated to the
 * correct position relative to the map.
 *
 * Also processes the objects, rotating them to correspond with segment
 * rotations. The objects are modified in place.
 */
std::vector<std::vector<Line> > SegmentStitching::processSegments(const std::vector<std::vector<Line> >& linesInSegments,
                                                                  mapping_msgs::SegmentObjectVector& allSegmentObjects){
    ROS_INFO("==================== Stitching segments ====================");
    // Keep a list of the positions of the robot at the beginning and end of
    // each segment, relative to the map, as opposed to each segment.
    std::vector<pcl::PointXYZ> segmentPointChain;
    //segmentPointChain.push_back(pcl::PointXYZ(0,0,0)); // chain starts at the origin
    std::vector<std::vector<Line> > stitchedLines;
    std::vector<mapping_msgs::ObjectVector> segmentObjects = allSegmentObjects.segmentObjects;
    // update this point every loop to make it correspond to the start point of
    // the segment in the global frame
    pcl::PointXYZ segmentGlobalStart(0,0,0);
    int xDir=0;		// direction x
    int yDir=1;		// direction y
    int rotation=0; // assume integer rotations to avoid float errors
    /*float xEnd=0;
      float yEnd=0;*/
	
    for (size_t i = 0; i < linesInSegments.size(); i++) {
        ROS_INFO("---------- Processing segment %d ----------", (int)i);
        ROS_INFO_STREAM("Segment start point: " << segmentGlobalStart);
        // End point of the segment is at the end of the list. Don't need to
        // extract the first point because the values are all zero.
        std::vector<mapping_msgs::SegmentPoint> segList = mapSegments[i].pointList;
        mapping_msgs::SegmentPoint segmentEnd = segList.back();
        
        // Extract the points from the segmentpoint. Start point for the segment
        // should always be (0,0,0). The end point corresponds to the position
        // of the robot at the end of the segment. We assume no motion in the x
        // direction.
        float odomDist = segmentEnd.odometry.distanceTotal;
        pcl::PointXYZ segmentEndPoint(xDir * odomDist, yDir * odomDist, 0);
        ROS_INFO_STREAM("Initial segment endpoint: " << segmentEndPoint);
        
        // For segments after the first one, need to modify the xdir and ydir to
        // correspond to the turn direction of the previous segment
        if (i != 0){
            int turnDirection = mapSegments[i-1].turnDirection;
            if (turnDirection == mapping_msgs::MapSegment::LEFT_TURN){
                ROS_INFO("Segment %d is a left turn from the previous segment (rotated 90)", (int)i);
                if (1==xDir && 0==yDir){ // going along x axis -> switch to going along y
                    xDir=0;
                    yDir=1;
                } else if (0==xDir && 1==yDir){ // going along y -> switch to going backwards on x
                    xDir=-1;
                    yDir=0;
                } else if (-1==xDir && 0==yDir){ // going backwards along x -> switch to going backwards on y
                    xDir=0;
                    yDir=-1;
                } else { // going backwards along y -> switch to going along x
                    xDir=1;
                    yDir=0;
                }
                rotation+=90;
            } else if (turnDirection == mapping_msgs::MapSegment::RIGHT_TURN){
                ROS_INFO("Segment %d is a right turn from the previous segment (rotated -90)", (int)i);
                if (1==xDir && 0==yDir){
                    xDir=0;
                    yDir=-1;
                } else if (0==xDir && -1==yDir){
                    xDir=-1;
                    yDir=0;
                } else if (-1==xDir && 0==yDir){
                    xDir=0;
                    yDir=1;
                } else {
                    xDir=1;
                    yDir=0;
                }
                rotation-=90;
            } else if (turnDirection == mapping_msgs::MapSegment::U_TURN){
                ROS_INFO("Segment %d is a u turn from the previous segment (rotated 180)", (int)i);
                if (xDir!=0){
                    xDir=-xDir;
                } else if (yDir!=0){
                    yDir=-yDir;
                }
                rotation+=180;
            } else {
                ROS_ERROR("Received map segment with invalid turn state.");
            }
        }

        // Reset rotation to be in bounds [180, -180]
        if (rotation > 180){
            rotation = rotation - 360;
        } else if (rotation < -180){
            rotation = rotation + 360;
        }

        ROS_INFO("Rotation is now %d", rotation);
            
        std::vector<Line> tmpLines;
        // loop over lines in the segment
        for(size_t j = 0; j < linesInSegments[i].size(); j++){
            ROS_INFO("Processing line %d", (int)j);
            Line tmpLine = linesInSegments[i][j];
            ROS_INFO_STREAM("" << tmpLine);
            // if the segment is rotated in the global frame, rotate each
            // line accordingly
            if (rotation != 0){
                tmpLine = rotateLine(tmpLine,rotation);
            }
            // Translate both points on the line from their current position
            // relative to the origin to the starting point of the line in
            // the global frame.
            ROS_INFO_STREAM("Translating line according to " << segmentGlobalStart);
            tmpLine.start = tmpLine.start + segmentGlobalStart;
            tmpLine.end = tmpLine.end + segmentGlobalStart;

            ROS_INFO_STREAM("Translated line: " << tmpLine);
            tmpLines.push_back(tmpLine);
        }
        stitchedLines.push_back(tmpLines);

        // loop over objects in this segment and rotate and translate them.
        for (size_t obj = 0; obj < segmentObjects[i].objects.size(); obj++) {
            mapping_msgs::Object& found = segmentObjects[i].objects[obj];

            // rotate the point around the origin
            if (rotation != 0){
                found.location = PCLUtil::rotatePointAroundOriginXY(found.location, rotation);
            }
            // translate it to its location in the rotated segment.
            found.location.x += segmentGlobalStart.x;
            found.location.y += segmentGlobalStart.y;
        }
            
        //Just add the difference and change the segmentEndPoint x and y
        float newX = xDir * segmentEnd.odometry.distanceTotal + segmentGlobalStart.x;
        float newY = yDir * segmentEnd.odometry.distanceTotal + segmentGlobalStart.y;
        segmentEndPoint = pcl::PointXYZ(newX, newY, 0);
        segmentPointChain.push_back(segmentEndPoint);

        ROS_INFO("X direction: %d, Y direction: %d", xDir, yDir);
        segmentGlobalStart = segmentEndPoint;
    }

    for (size_t i = 0; i < segmentPointChain.size(); i++) {
        ROS_INFO_STREAM("Segment point " << i << ": " << segmentPointChain[i]);
    }

    return stitchedLines;

}
int mainLoop()
{   
    wchar_t ch = 0;
    int running = 1;
    int roundEnd = 0;

    int i = 0;
    while(running)
    {
        ch = getChar();
        if(ch == 27)
           break;

        /*
         * Rotates specified lines the
         * specified amount (in radians
         */
        rotateLine(line1,M_PI/1000);
        rotateLine(line2,M_PI/900);
        rotateLine(line3,-M_PI/900);

        /*
         * Firethruster handles input
         */
        fireThruster(ch);
        moveLander();

        /*
         * Time to sleep between frames
         */
        usleep(1000);

        if(roundEnd)
        {
            roundEnd = 0;
            clearPrintScreen();
            usleep(1000000);
            if(fuel < 0)
                running = 0;
        }

        /*
         * Convert fuel int to string 
         * and add to textVector
         */
        char fuelstr[7];
        sprintf(fuelstr,"%d",fuel_int);
        changeText(fuel,fuelstr);
        char scorestr[7];
        sprintf(scorestr,"%d",score_int);
        changeText(score,scorestr);

        draw();

        switch(detectWin(platform1,platform2))
        {
            case 0:
                break;
            case 1:
                printToScreen("Crashed!");
                draw();
                resetLander();
                roundEnd = 1;
                break;
            case 21:
                printToScreen("Landed too hard :( -100 fuel");
                score_int += 50;
                fuel_int -= 100;
                draw();
                resetLander();
                roundEnd = 1;
                break;
            case 22:
                printToScreen("Landed too hard :( -100 fuel");
                score_int += 75;
                fuel_int -= 100;
                draw();
                resetLander();
                roundEnd = 1;
                break;
            case 31:
                printToScreen("PERFECT LANDING!");
                score_int += 300;
                draw();
                resetLander();
                roundEnd = 1;
                break;
            case 32:
                printToScreen("PERFECT LANDING!");
                score_int += 200;
                draw();
                resetLander();
                roundEnd = 1;
                break;
            case 4:
                printToScreen("Out of fuel!");
                draw();
                resetLander();
                roundEnd = 1;
        }

    }
    exitVect();
    return 0;
}
Esempio n. 4
0
int main(void) {
_delay_ms(100);
	// IO port initialisation
	port_direction_init();
	
	centre.x = ((float)LCD_WIDTH-1.0)/(float)2.0;	//the X origin offset
	centre.y = ((float)LCD_HEIGHT-1.0)/(float)2.0;	//the Y origin offset
	
	//set up the compass serial port
	compass_init();
	LCD_init();
	SREG |= 0x80;	//Set the global interrupt enable bit in the Status Register SREG, see section 6.3.1 of the datasheet.
	LCD_clear();
	
	//north
	fixedPointLine northline1;
	northline1.start.x = fip(centre.x);
	northline1.start.y = fip(0);
	northline1.end.x = fip(37);
	northline1.end.y = fip(centre.y);
	fixedPointLine northline2;
	northline2.start.x = fip(centre.x);
	northline2.start.y = fip(0);
	northline2.end.x = fip(46);
	northline2.end.y = fip(centre.y);
	//north small
	fixedPointLine northsmallline1;
	northsmallline1.start.x = fip(41.5);
	northsmallline1.start.y = fip(15);
	northsmallline1.end.x = fip(46);
	northsmallline1.end.y = fip(23.5);
	fixedPointLine northsmallline2;
	northsmallline2.start.x = fip(41.5);
	northsmallline2.start.y = fip(15);
	northsmallline2.end.x = fip(37);
	northsmallline2.end.y = fip(23.5);
	//horizontal line
	fixedPointLine horizontalline;
	horizontalline.start.x = fip(30);//37;
	horizontalline.start.y = fip(centre.y);
	horizontalline.end.x = fip(53);//46;
	horizontalline.end.y = fip(centre.y);
	//south
	fixedPointLine southline1;
	southline1.start.x = fip(centre.x);
	southline1.start.y = fip(47);
	southline1.end.x = fip(46);
	southline1.end.y = fip(centre.y);
	fixedPointLine southline2;
	southline2.start.x = fip(centre.x);
	southline2.start.y = fip(47);
	southline2.end.x = fip(37);
	southline2.end.y = fip(centre.y);
	
	fixedPointPolygon northTriangle;
	northTriangle.num_vertices = 4;
	fixedPointCoord vertices[northTriangle.num_vertices];
	vertices[0].x = fip(centre.x); //point
	vertices[0].y = fip(0);
	vertices[1].x = fip(46); //bottom right
	vertices[1].y = fip(centre.y);
	vertices[2].x = fip(centre.x); //middle arrow
	vertices[2].y = fip(19);
	vertices[3].x = fip(37); //bottom left
	vertices[3].y = fip(centre.y);
	northTriangle.vertices = vertices; //vertices points to the start of the array
	
	fixedPointPolygon rotatedPoly;
	fixedPointEdgeTable globalEdgeTable;
	while (1) {
	//TODO: use a timed interrupt to send the LCD update
	//TODO: stop the LCD update during the compass update (MAYBE??)
	//TODO: name public and private headers
	//TODO: separate out LCD functions
		updated = 0;
		compass_transmit((char) 0x12);
		while (!updated) {
		}
		LCD_clear_buff();
		
		//north
		//draw_line_l(rotateLine(northline1, angle));
		//draw_line_l(rotateLine(northline2, angle));
		//north small
		/*draw_line_l(rotateLine(northsmallline1, angle));
		draw_line_l(rotateLine(northsmallline2, angle));*/
		//horizontal line
		//draw_line_l(rotateLine(horizontalline, angle));
		//south
		draw_line_l(rotateLine(southline1, angle));
		
		if (rotatePolygon(&northTriangle, angle, &rotatedPoly)) {
			if (initialise_global_edge_table(&rotatedPoly, &globalEdgeTable)) {
			//remember a logical check that after initialisation, there are at least 2 edges!
				draw_polygon(&globalEdgeTable);
				free(globalEdgeTable.edges);
				globalEdgeTable.edges = NULL;
				draw_line_l(rotateLine(southline2, angle));
			}
			free(rotatedPoly.vertices);
			rotatedPoly.vertices = NULL;
		}
		
		//steps:
		//rotate polygon - check
		//http://www.cs.rit.edu/~icss571/filling/how_to.html
		//initializing should return a bool for successful or not (cos of mallocing)
		//initialize edges
		//initializing global edge table (sorted) (size should be total number of edges)
		//initializing parity
		//initializing the scan-line
		//initializing active edge table (size should be number of edges)
		//fill polygon
		//aim for a draw_scene function (pass an array of polygons and an angle)
		//  if N is 2 for a polygon, cast its array to a line

		LCD_update();

 	}
}