Exemple #1
0
	//-------------------------------------------------------------------------------------
	GUIManager::GUIManager(Ogre::Root *root, TankWarWorld *world, Ogre::RenderWindow *window, Ogre::SceneManager *sceneMgr, InputHandler* inputHandler, TankFactory* tankFactory, CollisionManager *mCollisionManager):
		mRoot(root), mWorld(world), mWindow(window), mSceneMgr(sceneMgr), mInputHandler(inputHandler), tankFactory(tankFactory), mCollisionManager(mCollisionManager)
	{
		setupVariables();
		initGUI();
		setupMenuGUI();

		miniMap();
		
	}
Exemple #2
0
//--------------------------------------------------------------
void ofApp::setup()
{
    ofSetFrameRate(FRAMERATE);
    // Setup Variables
    setupVariables();
    // Looks for masks inside of the Masks folder
    setupMasks();
    // Setup the GUI
    setupGUI();
    // Setup the Timer
    setupTimer();
    // Setup Custom openCV Class
    openCV.setup(CAM_WIDTH,CAM_HEIGHT,FRAMERATE);    
}
int main(int argc, char **argv)
{
	//set up variables (using names inside flockVars and forceVars structs instead of the arrays because they're easier to remember)
	//temporarily assume worst case
	setupVariables(param_32plane_500m);
	
	//standard ROS startup
	ros::init(argc, argv, "collisionAvoidance");
	ros::NodeHandle n;
	
	//subscribe to telemetry outputs and create clients for the goToWaypoint and requestWaypointInfo services
	ros::Subscriber sub = n.subscribe("telemetry", 1000, telemetryCallback);
	goToWaypointClient = n.serviceClient<AU_UAV_ROS::GoToWaypoint>("go_to_waypoint");
	requestWaypointInfoClient = n.serviceClient<AU_UAV_ROS::RequestWaypointInfo>("request_waypoint_info");
	
	//initialize counting
	count = 0;

	//needed for ROS to wait for callbacks
	ros::spin();
		
	return 0;
}
void telemetryCallback(const AU_UAV_ROS::TelemetryUpdate::ConstPtr &msg)
{    
	AU_UAV_ROS::GoToWaypoint goToWaypointSrv;
	AU_UAV_ROS::RequestWaypointInfo requestWaypointInfoSrv;
	
	int planeID = msg->planeID;
	
	/* request this plane's current normal destination */
	requestWaypointInfoSrv.request.planeID = planeID;
	requestWaypointInfoSrv.request.isAvoidanceWaypoint = false;
	requestWaypointInfoSrv.request.positionInQueue = 0;

	if (!requestWaypointInfoClient.call(requestWaypointInfoSrv)){
		ROS_ERROR("Did not receive a response from the coordinator");
		return;
	}
	
	destLatArray[planeID] = requestWaypointInfoSrv.response.latitude;
	destLonArray[planeID] = requestWaypointInfoSrv.response.longitude;
	
	// check for the total number of planes present to use the correct parameters
	if (planeID+1 > maxPlanesFound)	maxPlanesFound++;

	// check the positions of all the waypoints and planes to see the field size for the correct parameters
	// it IS possible for a larger scenario to seem like a smaller scenario by chance, but that should be okay
	if (planeID == maxPlanesFound-1)
	{
		fieldSize = 500;
		for (unsigned int i = 0; i < maxPlanesFound; i += 1)
		{
			// check waypoints
			if (destLatArray[i] < (SOUTH_MOST_LATITUDE_500M - LATITUDE_EPSILON) ||
			destLonArray[i] > (EAST_MOST_LONGITUDE_500M + LONGITUDE_EPSILON))			
			{
				fieldSize = 1000;
				break;
			}
		}
		
		// use the plane and waypoint information to find the correct parameters (update once per cycle)
		if (fieldSize == 500){
			if (maxPlanesFound <= 4){
				setupVariables(param_4plane_500m);
			}
			else if (maxPlanesFound <= 8){
				setupVariables(param_8plane_500m);
			}
			else if (maxPlanesFound <= 16){
				setupVariables(param_16plane_500m);
			}
			else if (maxPlanesFound <= 32){
				setupVariables(param_32plane_500m);
			}
			else
			{
				std::cout << "plane number error: more than 32 UAVs found- using 32 plane case" << std::endl;
				setupVariables(param_32plane_500m);
			}
		}
	
		else if (fieldSize == 1000){
			if (maxPlanesFound <= 4){
				setupVariables(param_4plane_1000m);
			}
			else if (maxPlanesFound <= 8){
				setupVariables(param_8plane_1000m);
			}
			else if (maxPlanesFound <= 16){
				setupVariables(param_16plane_1000m);
			}
			else if (maxPlanesFound <= 32){
				setupVariables(param_32plane_1000m);
			}
			else
			{
				setupVariables(param_32plane_1000m);
				std::cout << "plane number error: more than 32 UAVs found- using 32 plane case" << std::endl;
			}
		}
		
		else std::cout << "field size error: invalid field size determined (this should never happen)" << std::endl;

		std::cout << "Using parameters for a " << fieldSize << "m field and " << maxPlanesFound << " UAVs" << std::endl;
	}
	
	/* 
	Remove any planes that have been involved in a collision.
	Note: This function is made for use with the evaluator node, and may not work optimally in the field.
	To check for collisions, it compares the current time with the last update time of each of the UAVs.  
	If the values differ by more than three seconds, it is assumed the plane has been deleted.  However, 
	packet losses / network latency may render issues in the real world.
	*/
	checkCollisions();
	
	/* 
	if (plane has reached current destination waypoint)
		move on to next normal destination waypoint in queue
	*/
	if (findDistance(msg->currentLatitude, msg->currentLongitude, 
					requestWaypointInfoSrv.response.latitude, 
					requestWaypointInfoSrv.response.longitude) < COLLISION_THRESHOLD){

		/* request next normal destination */
		requestWaypointInfoSrv.request.positionInQueue = 1;

		if (!requestWaypointInfoClient.call(requestWaypointInfoSrv)){
			ROS_ERROR("Did not recieve a response from the coordinator");
			return;
		}
	}

	/* 
	Pseudocode for the following code lines.
	if (this plane is not in the map of planes and the telemetry update indicates that the plane is or has been moving towards a destination)
		if (the plane had been flying but we previously detected a collision and removed it)
			return - the plane is dead; the simulator is lagging behind 
		else
			the plane has registered a new TelemetryUpdate 
	else 
		return - the plane has just been initialized but it is not moving torwards a waypoint as of now 
	*/
	if (pobjects.find(planeID) == pobjects.end() && msg->currentWaypointIndex != -1){ 
		
		if (msg->currentWaypointIndex > 0){
			/* This plane is dead; it had previously been moving but was in a collision.
			The simulator is lagging behind and still reporting a telemetry update */
			return;
		}
		else{
			/* 
			a new plane has registered a TelemetryUpdate where the destination is not (0, 0)
			create new PlaneObject, collision radius is set to the distance traveled in one second
			*/
			AU_UAV_ROS::PlaneObject newPlane(MPS_SPEED, *msg); /* */
			pobjects[planeID] = newPlane; /* put the new plane into the map */

			/* update the destination of the PlaneObject with the value found with the requestWaypointInfoSrv call */
			AU_UAV_ROS::waypoint newDest; 

			newDest.latitude = requestWaypointInfoSrv.response.latitude;
			newDest.longitude = requestWaypointInfoSrv.response.longitude;
			newDest.altitude = requestWaypointInfoSrv.response.altitude;

			pobjects[planeID].setDestination(newDest);
		}
	}
	else if (pobjects.find(planeID) == pobjects.end()) /* new plane without waypoint set */
		return; 
	
	/* 
	Note: The requestWaypointInfo service returns a waypoint of -1000, -1000 when the UAV it cannot retrieve a destination from
	queue.

	Pseudocode:
	if (the plane has no destination){
		- for simulations, silence any force from this UAV so it does not affect flight paths by giving it an impossible location
		- update with the new time of latest update to avoid a false detection of a collision
	}
	else{
		update the plane with the new telemetry information

		if (the plane's destination has changed)
			update the map entry of the plane with this information
	}
	*/
	if (requestWaypointInfoSrv.response.latitude == -1000){ /* plane has no waypoints to go to */
		/* 
		useful for simulations, remove in real flights;		
		set location of finished planes to -1000, -1000 so no repulsive force is felt from this plane
		*/
		pobjects[planeID].setLatitude(-1000);
		pobjects[planeID].setLongitude(-1000);

		pobjects[planeID].update(); /* update the time of last update for this plane to acknowledge it is still in the air */
		return; 
	}
	else{
		pobjects[planeID].update(*msg); /* update plane with new position */

		/* if (destination has changed)
			update pobjects[planeID] with new destination */
		if (((pobjects[planeID].getDestination().latitude - requestWaypointInfoSrv.response.latitude) > EPSILON)
				|| ((pobjects[planeID].getDestination().longitude - requestWaypointInfoSrv.response.longitude) > EPSILON)
				|| ((pobjects[planeID].getDestination().latitude - requestWaypointInfoSrv.response.latitude) < EPSILON)
				|| ((pobjects[planeID].getDestination().longitude - requestWaypointInfoSrv.response.longitude) < EPSILON)){
			AU_UAV_ROS::waypoint newDest;

			newDest.latitude = requestWaypointInfoSrv.response.latitude;
			newDest.longitude = requestWaypointInfoSrv.response.longitude;
			newDest.altitude = requestWaypointInfoSrv.response.altitude;

			pobjects[planeID].setDestination(newDest);
		}
	}

	//form flocks	
	formFlocks();
	
	//organize flock information
	checkFlocks();
	
	// give the UAVs their flock numbers
	for (unsigned int i = 0; i < flocks.size(); i += 1)
	{
		for (unsigned int j = 0; j < flocks[i].size(); j += 1)
		{
			flocks[i][j]->setFlock(i);
		}
	}

	/* Find the force acting on this UAV.  The plane is attracted to its waypoint or leader, and repelled from other UAVs */
	AU_UAV_ROS::mathVector force = calculateForces(pobjects[planeID], pobjects, flocks, forceVars);

	/* 
	Create a goToWaypoint service to send to the coordinator based on the force vector just calculated.  The destination will be one
	second away from the current position.
	*/
	goToWaypointSrv = updatePath(msg, force);

	goToWaypointSrv.request.isAvoidanceManeuver = true; 
	goToWaypointSrv.request.isNewQueue = true;

	if (goToWaypointClient.call(goToWaypointSrv)){
		count++;
		//ROS_INFO("Received response from service request %d", (count-1));
	}
	else{
		ROS_ERROR("Did not receive response");
	}
}
Exemple #5
0
//------------------------------------------------------------------------------
int __attribute__((OS_main)) main(void)
{
	setupA();
	setupB();
	setupVariables();

	dnaUsbInit();

	INSTALL_MORLOCK_DEFAULTS;
	saveEEPROMConstants();

	loadEEPROMConstants();

	// 12000000 / (64 * 94) = 1994.680 interrupts per second
	// accomplished by using timer0 in waveform generation mode 2
	TCCR0B = 1<<CS01 | 1<<CS00; // set 8-bit timer prescaler to div/64
	OCR0A = 94;
	TCCR0A = 1<<WGM01; 
	TIMSK0 = 1<<OCIE0A; // mode 2, reset counter when it reaches OCROA

	TCCR1B = 1<<WGM12 | 1<<CS12;// CTC for OCR1A, clock select

	// set up A2D
	ADMUX = 1<<MUX0; // A1, Vcc ref
	ADCSRA = 1<<ADEN | 1<<ADPS2; // enable A2D, x16
	DIDR0 = ADC1D; // disable all digital function on A1
	ADCSRB = 1<<ADLAR; // knock off lower two bits, implementation is not that accurate

	PRR = 1<<PRUSI; // not using USI (yet)
	
	rnaInit();

	sei();


	_delay_ms(2); // let state settle, and make sure housekeeping ISR runs

	if( !triggerState && !consts.locked )
	{
		timesToBlinkLight = 1;
		inProgramMode = true;
	}

	for(;;)
	{
		PRR |= 1<<PRTIM1; // power down timer, don't waste power

		// spin until a fire condition is triggered from the ISR
		while( !startFireCycle )
		{
			sampleEye = false;

			if ( rnaRequestsConfigData )
			{
				usbRNAPacket[0] = RNATypeSetConfigData;
				for( unsigned char c=0; c<sizeof(consts); c++ )
				{
					usbRNAPacket[c+1] = ((unsigned char *)&consts)[c];
				}
				rnaSend( rnaRequestsConfigData, usbRNAPacket, sizeof(consts) + 1 );
				rnaRequestsConfigData = 0;
			}

			if ( !millisecondCountBox && consts.eyeEnabled )
			{
				millisecondCountBox--;
				digitizeEye();
				isLedOn = eyeBlocked ? true : false;
			}

			if ( eepromConstantsDirty )
			{
				isLedOn = true;
				setLedOn();
				eepromConstantsDirty = false;
				saveEEPROMConstants();
				isLedOn = false;
			}

			if ( rnaPacketAvail )
			{
				isLedOn = true;
				setLedOn();
				rnaPacketAvail = false;
				_delay_ms( 50 );
				rnaSend( usbRNATo, usbRNAPacket, usbRNAPacketExpected );
				isLedOn = false;
			}
		}

		sampleEye = true;

		// set up the timer
		PRR &= ~(1<<PRTIM1); // timer back on
		TCNT1 = 0; // reset the timer
		TIFR1 |= 1<<OCF1A; // reset compare match

		if ( shotsInString < consts.rampEnableCount )
		{
			shotsInString++;
		}

		// setup complete, cycle the marker
		if ( consts.singleSolenoid )
		{
			cycleSingleSolenoid();
		}
		else
		{
			cycleDoubleSolenoid();
		}

		// bursting? if so count it down
		if ( burstCount && --burstCount )
		{
			startFireCycle = true;
		}
		else if ( currentFireMode != ceFullAuto )
		{
			startFireCycle = false;
		}

		isLedOn = false;

		// make sure at least this much time elapses at the end of a fire cycle
		millisecondCountBox = consts.shortCyclePreventionInterval;
		while( millisecondCountBox );

		while( !(TIFR1 & 1<<OCF1A) ); // wait for end of fire cycle

		if ( currentFireMode == ceRamp && startFireCycle && (consts.rampTopMode != ceSemi) ) // officially hit top rate, blow guts out
		{
			// a shot was scheduled at the maximum rate it could be, go
			// ahead and shift up to whatever top mode the user wanted
			currentFireMode = consts.rampTopMode;
			scheduleShotBox = 0;
			scheduleShotRate = 0;
		}
	}
}
	Result iterate() {
		setupVariables();



		// for now we use a iteration counter to protect us from infinite loops
		// TODO< implement loop detection scheme, basic idea
		//       * we manage a fixed sized array as a sliding window or the hashes of the operations
		//       * if we detect a loop we apply bland's rule to resolve it (is the rule detection realy neccesary?)
		//
		//
		//       * every operation (pivot column, pivot row, number of pivot element itself) gets an hash
		//       * at each iteration we subtract the previous hash and add the current hash
		//       * if the hash doesn't change in n iteration(where n == 2 for the simple loop) we are looping
		// >

		// TODO< implement https://en.wikipedia.org/wiki/Bland's_rule >

		unsigned iterationCounter = 0;
		const unsigned MaximalIterationCounter = 128;

		for(;;) {
			iterationCounter++;
			if( iterationCounter > MaximalIterationCounter ) {
				return Result(Result::EnumSolverState::TOOMANYITERATIONS);
			}

			bool foundMaximumColumn;

			const int pivotColumnIndex = searchMinimumColumn(foundMaximumColumn);
			// all values in the target value row are < 0.0, done
			if( !foundMaximumColumn ) {
				return Result(Result::EnumSolverState::FOUNDSOLUTION);
			}

			//std::cout << "min column " << pivotColumnIndex << std::endl;

			if( areAllEntriesOfPivotColumnNegativeOrZero(pivotColumnIndex) ) {
				// solution is unbounded

				return Result(Result::EnumSolverState::UNBOUNDEDSOLUTION);
			}

			// divide numbers of pivot column with right side and store in temporary vector
			Eigen::Matrix<Type, Eigen::Dynamic, 1> minRatioVector = divideRightSideWithPivotColumnWhereAboveZero(pivotColumnIndex);

			//std::cout << "temporary vector" << std::endl;
			//std::cout << minRatioVector << std::endl;

			const int minIndexOfTargetFunctionCoefficient = getMinIndexOfMinRatioVector(minRatioVector);
			const bool positiveMinRatioExists = doesPositiveMinRatioExist(minRatioVector);
			if( !positiveMinRatioExists ) {
				// solution is unbounded

				return Result(Result::EnumSolverState::UNBOUNDEDSOLUTION);
			}

			const int pivotRowIndex = minIndexOfTargetFunctionCoefficient;

			//std::cout << "pivotRowIndex " << pivotRowIndex << std::endl;

			Type pivotElement = matrix(pivotRowIndex, pivotColumnIndex);

			// divide the pivot row with the pivot element
			matrix.block(pivotRowIndex,0, 1, matrix.cols()) /= pivotElement;

			// TODO< assert that pivot elemnt is roughtly 1.0 >



			// do pivot operation

			for(int pivotRowIteration = 0; pivotRowIteration < matrix.rows(); pivotRowIteration++ ) {
				if( pivotRowIteration == pivotRowIndex ) {
					continue;
				}

				Type iterationElementAtPivotColumn = matrix(pivotRowIteration, pivotColumnIndex);
				matrix.block(pivotRowIteration, 0, 1, matrix.cols()) -= (matrix.block(pivotRowIndex, 0, 1, matrix.cols()) * iterationElementAtPivotColumn);
			}

			// set the variable identifier that we know which row of the matrix is for which variable
			variables[pivotRowIndex] = Variable(Variable::EnumType::NAMEME, pivotColumnIndex);

			//std::cout << matrix << std::endl;
			
		}
	}