Exemple #1
0
static void 
MultiActivate(
        Widget wid,
        XEvent *buttonEvent,
        String *params,
        Cardinal *num_params)
{
  /* When a multi click sequence occurs and the user Button Presses and
   * holds for a length of time, the final release should look like a
   * new/separate activate.
   */
  XmArrowButtonWidget aw = (XmArrowButtonWidget) wid;
  
  if (aw->arrowbutton.multiClick == XmMULTICLICK_KEEP)
    {
      if ((buttonEvent->xbutton.time - aw->arrowbutton.armTimeStamp) > 
	  XtGetMultiClickTime(XtDisplay(aw)))
	aw->arrowbutton.click_count = 1;
      else
	aw->arrowbutton.click_count++;
      
      ActivateCommon((Widget) aw, buttonEvent);
      Disarm ((Widget) aw, buttonEvent, params, num_params);
    }
}
Exemple #2
0
Missile::Missile(const ShipType::Id &shipId, Body *owner, int power)//: Ship(shipId)
{
	if (power < 0) {
		m_power = 0;
		if (shipId == ShipType::MISSILE_GUIDED) m_power = 1;
		if (shipId == ShipType::MISSILE_SMART) m_power = 2;
		if (shipId == ShipType::MISSILE_NAVAL) m_power = 3;
	} else
		m_power = power;

	m_owner = owner;
	m_type = &ShipType::types[shipId];

	SetMass(m_type->hullMass*1000);

	SetModel(m_type->modelName.c_str());
	SetMassDistributionFromModel();

	SetLabel(Lang::MISSILE);

	Disarm();

	SetFuel(1.0);
	SetFuelReserve(0.0);

	m_curAICmd = 0;
	m_aiMessage = AIERROR_NONE;
	m_decelerating = false;

	Propulsion::Init( this, GetModel(), m_type->fuelTankMass, m_type->effectiveExhaustVelocity, m_type->linThrust, m_type->angThrust );

}
Exemple #3
0
Missile::Missile(ShipType::Id shipId, Body *owner, int power): Ship(shipId)
{
	if (power < 0) {
		m_power = 0;
		if (shipId == ShipType::MISSILE_GUIDED) m_power = 1;
		if (shipId == ShipType::MISSILE_SMART) m_power = 2;
		if (shipId == ShipType::MISSILE_NAVAL) m_power = 3;
	} else
		m_power = power;

	m_owner = owner;
	SetLabel(Lang::MISSILE);
	Disarm();
}
Exemple #4
0
static void
MultiActivate(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
    XButtonEvent *ev = (XButtonEvent *)event;
    XmDrawnButtonCallbackStruct cbs;

    DEBUGOUT(_LtDebug(__FILE__, w, "DrawnB: MultiClick\n"));

    if (DB_MultiClick(w) == XmMULTICLICK_KEEP)
    {
	Time mctime = XtGetMultiClickTime(XtDisplay(w));

	if ((event->xbutton.time - DB_ArmTimeStamp(w)) < mctime)
	{
	    DB_ClickCount(w)++;
	}
	else
	{
	    DB_ClickCount(w) = 1;
	}

	DB_Armed(w) = False;

	if (XtIsRealized(w))
	    XtClass(w)->core_class.expose(w, event, NULL);

	if (ev->type == KeyPress || ev->type == KeyRelease ||
	    ((ev->x >= 0 && ev->x < XtWidth(w)) &&
	     (ev->y >= 0 && ev->y < XtHeight(w))))
	{
	    if (!Lab_SkipCallback(w) && DB_ActivateCallback(w))
	    {
		cbs.reason = XmCR_ACTIVATE;
		cbs.event = event;
		cbs.click_count = DB_ClickCount(w);

		XFlush(XtDisplay(w));

		XtCallCallbackList(w,
				   DB_ActivateCallback(w),
				   (XtPointer)&cbs);
	    }
	}

	Disarm(w, event, params, num_params);
    }
}
// This function is never called if there is a calibration issue.
// called in true section of if (RX_Snapshot[RXChannel_THR] < STICKThrottle_ARMING) 
void HandleSticksForArming (void)
{
	
	if ((UIEnableStickCommands==false) || (ActiveRXIndex!=1) || (!IS_TX2_GOOD)) return ; // you cannot use Primary to Arm and Disarm
	SystemErrorType = CLR_SYS_ERR_SIGNAL;
	
	if (TCNT1_X_snapshot1==0)  TCNT1_X_snapshot1 = CurrentTCNT1_X; // start counting
		
		// DisArm Check
		if (IsArmed == true) 
		{
			if (RX_Latest[ActiveRXIndex][RXChannel_RUD] > STICK_LEFT)
			{ // Check DisArming manually.
				bResetTCNR1_X  = false;
				if ( (CurrentTCNT1_X - TCNT1_X_snapshot1) > STICKPOSITION_LONG_TIME )
				{
					Disarm();
					return ;
				}
			}
			
			if (Config.AutoDisarm!=0)
			{ // check auto disArm
				if (TCNT_X_snapshotAutoDisarm > CurrentTCNT1_X ) TCNT_X_snapshotAutoDisarm = 0; // the CurrentTCNT1_X was high so the disarm condition never true.
				if (TCNT_X_snapshotAutoDisarm==0) TCNT_X_snapshotAutoDisarm = CurrentTCNT1_X; 
				if ((CurrentTCNT1_X - TCNT_X_snapshotAutoDisarm) > (DISARM_TIME * Config.AutoDisarm))
				{
					Disarm();
					return ;
				}
			}
			
		}			
		
		if (IsArmed == false) 
		{
			//int16_t Stick = (Config.RX_Mid[ActiveRXIndex][RXChannel_RUD] + RX_Latest[ActiveRXIndex][RXChannel_RUD] * RX_Div_Factor);
			if (RX_Latest[ActiveRXIndex][RXChannel_RUD]  < STICK_RIGHT)
			{	// Armin Check
				bResetTCNR1_X = false;
				if ( (CurrentTCNT1_X- TCNT1_X_snapshot1) > STICKPOSITION_LONG_TIME )
				{
					Arm();
					return ;
				}
			}					
		
			//set modes Quad , X-Quad
		
			if (RX_Latest[ActiveRXIndex][RXChannel_AIL]  > STICK_LEFT)
			{// X-QUAD MODE
				bResetTCNR1_X = false;
				if ( (CurrentTCNT1_X- TCNT1_X_snapshot1) > STICKPOSITION_LONG_TIME )
				{
					Config.QuadFlyingMode=QuadFlyingMode_X;
					LED_FlashOrangeLED (LED_LONG_TOGGLE,8);
					TCNT1_X_snapshot1 =0; // reset timer
				}
			}			
			else if ((RX_Latest[ActiveRXIndex][RXChannel_AIL]  < STICK_RIGHT))
				{	// QUAD COPTER MODE
					bResetTCNR1_X = false;
					if ( (CurrentTCNT1_X- TCNT1_X_snapshot1) > STICKPOSITION_LONG_TIME )
					{
						Config.QuadFlyingMode=QuadFlyingMode_PLUS;
						LED_FlashOrangeLED (LED_LONG_TOGGLE,4);
						TCNT1_X_snapshot1 =0; // reset timer
					}		
			
				} 
				
			// set mode ACRO , Leveling
			else if ((RX_Latest[ActiveRXIndex][RXChannel_ELE]  < STICK_RIGHT))
				{	//nFlyingModes = FLYINGMODE_LEVEL;
					bResetTCNR1_X = false;
					if ( (CurrentTCNT1_X- TCNT1_X_snapshot1) > STICKPOSITION_LONG_TIME )
					{
						nFlyingModes = FLYINGMODE_LEVEL;
						LED_FlashOrangeLED (LED_LONG_TOGGLE,8);
						TCNT1_X_snapshot1 =0; // reset timer
					}		
			
				} 
			else if ((RX_Latest[ActiveRXIndex][RXChannel_ELE]  > STICK_LEFT))
				{	//nFlyingModes = FLYINGMODE_ACRO;
					bResetTCNR1_X = false;
					if ( (CurrentTCNT1_X- TCNT1_X_snapshot1) > STICKPOSITION_LONG_TIME )
					{
						nFlyingModes = FLYINGMODE_ACRO;
						LED_FlashOrangeLED (LED_LONG_TOGGLE,4);
						TCNT1_X_snapshot1 =0; // reset timer
					}		
			
				} 
		}
	
}
void MainLoop(void)
{
	
	RX_CopyLatestReceiverValues();
	//RX_Snapshot_1 [RXChannel_THR]= RX_Snapshot[RXChannel_THR];
	RX_Snapshot   [RXChannel_THR]= RX_Latest[ActiveRXIndex][RXChannel_THR];
	Sensors_ReadAll();	
	
	
	
	
	ATOMIC_BLOCK(ATOMIC_FORCEON)
    {
      CurrentTCNT1_X = TCNT1_X;
    }

	IMU();
	
#ifdef DEBUG_ME
		// Sending Sensors & Motor Data 
		if (Config.RX_mode==RX_mode_SingleMode)
		{
			//LED_Orange=~LED_Orange;
#ifdef	UART_SEND_SENSORS			
			Send_Byte('S');
			Send_Data((void *)(&Sensors_Latest[0]),24);
			Send_Data((void *)(&MotorOut[0]),8);
			Send_Byte('E');
#else

			Send_Byte('I');
			Send_Data((void *)(&Sensors_Latest[0]),12);
			Send_Data((void *)(&AnglePitch),4);
			Send_Data((void *)(&AngleRoll),4);
			Send_Data((void *)(&CompAccZ),4);
			Send_Data((void *)(&MotorOut[0]),8);
			Send_Byte('E');
			
#endif
			
		}
#endif
 
	bResetTCNR1_X = true;
	
	
	if (Config.RX_mode==RX_mode_BuddyMode)
	{   // in Buddy mode AUX channel is used for instance switching.
		if (IS_TX2_GOOD)
		{
			if (RX_Latest[RX_MAIN][RXChannel_AUX] < STICK_RIGHT)
			{
				ActiveRXIndex = 0;		// use Primary RX
			}
			else
			{
				ActiveRXIndex = 1;		// use Secondary RX
			}
		}			
	}			
	
		
	////////// Slow Actions inside
	// HINT: you can try to skip this if flying to save time for more useful tasks as user cannot access menu when flying
	
	if (TCNT_X_snapshot2 == 0) TCNT_X_snapshot2 = CurrentTCNT1_X;
	else if ( ((CurrentTCNT1_X - TCNT_X_snapshot2) > 4) )  // TCNT1_X ticks in 32.768us
	{
		Menu_MenuShow();
		
		if (Config.VoltageAlarm > 0)
		{
			//Sensor_GetBattery();
			if (Sensors_Latest[V_BAT_Index] < Config.VoltageAlarm)
			{
				
				SystemErrorType = SET_SYS_ERR_VOLTAGE;
			}
			else
			{
				SystemErrorType = CLR_SYS_ERR_VOLTAGE;
				
			}
		}	
		if (SystemErrorType != SYS_ERR_NON)
		{
			Buzzer =~Buzzer ;	
		}
		else
		{
			Buzzer = OFF;
		}
		
		if (Config.RX_mode==RX_mode_SingleMode)
		{
				if ((FlyingModesToggle != LOW) && ( RX_Latest[RX_MAIN][RXChannel_AUX] < STICK_RIGHT ))
				{
					nFlyingModes = FLYINGMODE_ALTHOLD;
					FlyingModesToggle = LOW;
				} else
				if ((FlyingModesToggle != HIGH) && (RX_Latest[RX_MAIN][RXChannel_AUX] > STICK_LEFT ))
				{
					//LED_Orange=ON;
					nFlyingModes = FLYINGMODE_ACRO;
					FlyingModesToggle = HIGH;
				} else
				if ((FlyingModesToggle != MID) && (RX_Latest[RX_MAIN][RXChannel_AUX]< STICK_LEFT) && ( RX_Latest[RX_MAIN][RXChannel_AUX] > STICK_RIGHT ))
				{
					nFlyingModes = FLYINGMODE_LEVEL;
					FlyingModesToggle = MID;
					
				}
				
		}		
		//if ((IsArmed == true) && (RX_Snapshot[RXChannel_THR] < STICKThrottle_ARMING+160))
		//{ // calibrate when start flying
			//DynamicCalibration();
		//}			
		TCNT_X_snapshot2=0;
	}		
	
	//////////////// EOF Slow Loop
	
	if (RX_Snapshot[RXChannel_THR] < STICKThrottle_ARMING) 
	{	
		
		// Throttle is LOW
		// Here you can add code without caring about delays. As there quad is already off and on land.
		// here we test different positions of sticks to enable arm/disarm, Quad/X-Quad
		HandleSticksForArming();
		
		// Stop motors if Throttle Stick is less than minimum.
		ZEROMotors();
#ifndef DEBUG_ME
		// Disable when debug
		ZERO_Is();
		IMU_Reset(); // reset angles for gyro [STABLE MODE]
#endif
	}
	else
	{	// Throttle stick is NOT Down .... TAKE CARE
		
		if (IsArmed==false)
		{  // However we are still DisArmed
			ZEROMotors();
			
			// Sticks as Keyboard --- we are already disarmed to reach here.
			HandleSticksAsKeys();
#ifdef DEBUG_ME  
			// ENable when debug
			GetExpoPoint(RX_Latest[ActiveRXIndex][RXChannel_AIL]);
			RX_Snapshot	  [RXChannel_AIL] = (RXResult );
			GetExpoPoint(RX_Latest[ActiveRXIndex][RXChannel_ELE]);
			RX_Snapshot   [RXChannel_ELE] = (RXResult ); 
			RX_Snapshot   [RXChannel_RUD] = (RX_Latest[ActiveRXIndex][RXChannel_RUD] * 0.5 ); // version 0.9.9 
#endif			
		}
		else
		{	// MOTORS ARE ON HERE .... DANGEROUS
			
			
			TCNT_X_snapshotAutoDisarm = 0; // ZERO [user may disarm then fly slowly..in this case the qude will disarm once he turned off the stick...because the counter counts once the quad is armed..e.g. if it takes n sec to disarm automatically..user took n-1 sec keeping the stick low after arming then it will take 1 sec to disarm again after lowing the stick under STICKThrottle_ARMING
			
			// Armed & Throttle Stick > MIN . . . We should Fly now.
			GetExpoPoint(RX_Latest[ActiveRXIndex][RXChannel_AIL]);
			RX_Snapshot	  [RXChannel_AIL] = (RXResult);
			GetExpoPoint(RX_Latest[ActiveRXIndex][RXChannel_ELE]);
			RX_Snapshot   [RXChannel_ELE] = (RXResult); 
			RX_Snapshot   [RXChannel_RUD] = (RX_Latest[ActiveRXIndex][RXChannel_RUD] * 0.5 ); // version 0.9.9 
			
			
		
			
			// Add Throttle to Motors
			MotorOut[0] = RX_Snapshot[RXChannel_THR];
			MotorOut[1] = RX_Snapshot[RXChannel_THR];
			if (Config.FrameType == FRAMETYPE_QUADCOPTER)
			{
				MotorOut[2] = RX_Snapshot[RXChannel_THR];
				MotorOut[3] = RX_Snapshot[RXChannel_THR];	
			}
			else
			{
				MotorOut[2] = RX_Snapshot[RXChannel_THR];
			}

			
			// Add IMU control.
			if (Config.FrameType == FRAMETYPE_QUADCOPTER)
			{	// Quadcopter
				/*
				* The logic below depends on board orientation i.e. sensor orientation compared to motor directions.
				* the IMU in ACHRO mode is totally independent from user sticks ... so it does not matter how the user
				* flies his quad i.e. in X or PLUS .... it does not matter because it is handled in another code lines not here.
				* here we handle board orientation only.
				*/
				if (Config.BoardOrientationMode==QuadFlyingMode_X)
				{	// Board Orientation in X-Mode
					// {-1,1,1,-1} QUAD_ROL_X
					MotorOut[0] -= gyroRoll ;
					MotorOut[3] -= gyroRoll ;
					MotorOut[1] += gyroRoll ;
					MotorOut[2] += gyroRoll ;
					
					// {-1,-1,1,1} QUAD_AIL_X
					MotorOut[0] -= gyroPitch;
					MotorOut[1] -= gyroPitch;
					MotorOut[2] += gyroPitch;
					MotorOut[3] += gyroPitch;
					
				}
				else
				{	// Board Orientation in Plus-Mode
					// {0,1,0,-1} QUAD_ROL_PLUS
					MotorOut[1] += gyroRoll  ;
					MotorOut[3] -= gyroRoll  ;
				
					// {-1,0,1,0} QUAD_AIL_PLUS
					MotorOut[0] -= gyroPitch ;
					MotorOut[2] += gyroPitch ; 
				
				}
			}
			else
			{	// Balance Tri-Copter
				// NOT VALID if Board Orientation is X
					
				MotorOut[2] += gyroPitch * 1.34; // 4/3
					
				gyroPitch    = gyroPitch * 0.67; // 2/3
				MotorOut[0] -= gyroPitch  ;
				MotorOut[1] -= gyroPitch  ;
					
				gyroRoll = gyroRoll; // * 0.85;
				MotorOut[0] -= gyroRoll  ;
				MotorOut[1] += gyroRoll  ;
			}				
			
			
			/*
			*
			*	Pilot Control Logic.
			*	Handles signals from remote control in ACRO mode.
			*	in stabilization mode controls are added in IMU logic as angles.
			*/
			if (nFlyingModes == FLYINGMODE_ACRO)
			{
				if (Config.FrameType == FRAMETYPE_QUADCOPTER)
				{
				
					if (Config.QuadFlyingMode==QuadFlyingMode_X)
					{
						RX_Snapshot[RXChannel_AIL] = RX_Snapshot[RXChannel_AIL] * 0.63;		// because we fly X
						RX_Snapshot[RXChannel_ELE] = RX_Snapshot[RXChannel_ELE] * 0.63;
					
						// {0.63,-0.63,-0.63,0.63} QUAD_AIL_X
						MotorOut[0] += RX_Snapshot[RXChannel_AIL] ;
						MotorOut[3] += RX_Snapshot[RXChannel_AIL] ;
						MotorOut[1] -= RX_Snapshot[RXChannel_AIL] ;
						MotorOut[2] -= RX_Snapshot[RXChannel_AIL] ;
				
						// {0.63,0.63,-0.63,-0.63} QUAD_ELE_X
						MotorOut[0] += RX_Snapshot[RXChannel_ELE];
						MotorOut[1] += RX_Snapshot[RXChannel_ELE];
						MotorOut[2] -= RX_Snapshot[RXChannel_ELE];
						MotorOut[3] -= RX_Snapshot[RXChannel_ELE];
					
					}
					else
					{
				
						// {0.9,0,-0.9,0} QUAD_ELE_PLUS
						MotorOut[0] += RX_Snapshot[RXChannel_ELE] ; 
						MotorOut[2] -= RX_Snapshot[RXChannel_ELE] ; 
						// {0,-0.9,0,0.9} QUAD_AIL_PLUS	
						MotorOut[1] -= RX_Snapshot[RXChannel_AIL] ; 
						MotorOut[3] += RX_Snapshot[RXChannel_AIL] ;  
								
					}
				}
				else
				{ // TRICopter
					
						int8_t inv=1; // Flying in Y mode
						if (Config.QuadFlyingMode==QuadFlyingMode_X)
						{ // Flying in A mode
							inv = -1;
						}							
							// {0.5,0.5,1.1,X} TRI_ELE_FRONT
							MotorOut[2] -= inv * (RX_Snapshot[RXChannel_ELE]);	
							RX_Snapshot[RXChannel_ELE] = inv * RX_Snapshot[RXChannel_ELE] ;  
							MotorOut[0] += RX_Snapshot[RXChannel_ELE] ; 
							MotorOut[1] += RX_Snapshot[RXChannel_ELE] ; 
						
							// {1,-1,0,X} TRI_AIL_FRONT
							RX_Snapshot[RXChannel_AIL] = inv * RX_Snapshot[RXChannel_AIL];
							MotorOut[0] += RX_Snapshot[RXChannel_AIL] ; 
							MotorOut[1] -= RX_Snapshot[RXChannel_AIL] ;  
				}					
			}
			
			// ACC-Z & SONAR
			if (nFlyingModes != FLYINGMODE_ACRO)
			{
				// in stabilization mode ... activate Acc-Z & Sonar if enabled.
				
				double Landing;
				// Handles Sonar & ACC-Z (Z is always handles even if ALTHLD is false)
				Landing = IMU_HeightKeeping();
				MotorOut[0] += Landing;
				MotorOut[1] += Landing;
				if (Config.FrameType == FRAMETYPE_QUADCOPTER)
				{
					
					MotorOut[2] += Landing;
					MotorOut[3] += Landing;		
				}
				else
				{
					MotorOut[2] += Landing;
				}
													
										
			}
			
									
			if (Config.FrameType == FRAMETYPE_QUADCOPTER)
			{
				MotorOut[0] -= gyroYaw;
				MotorOut[2] -= gyroYaw;
				MotorOut[1] += gyroYaw;
				MotorOut[3] += gyroYaw;
			}
			else
			{
			
				MotorOut[3]  = (Config.ReverseYAW * gyroYaw) + SERVO_IN_MIDDLE; 
				MotorOut[3]  = MotorOut[3] - (Config.ReverseYAW * RX_Snapshot[RXChannel_RUD]);
			}						
			
			// Save motors from turning-off
            if (MotorOut[0]<MOTORS_IDLE_VALUE) MotorOut[0]=MOTORS_IDLE_VALUE;
            if (MotorOut[1]<MOTORS_IDLE_VALUE) MotorOut[1]=MOTORS_IDLE_VALUE;
            if (MotorOut[2]<MOTORS_IDLE_VALUE) MotorOut[2]=MOTORS_IDLE_VALUE;
            
									
			if (Config.FrameType == FRAMETYPE_QUADCOPTER)
			{
				if (MotorOut[3]<MOTORS_IDLE_VALUE) MotorOut[3]=MOTORS_IDLE_VALUE;
			}
			
		
			// Sending Sensors & Motor Data 
			if (Config.RX_mode==RX_mode_SingleMode)
			{
#ifdef	UART_SEND_SENSORS			
			Send_Byte('S');
			Send_Data((void *)(&Sensors_Latest[0]),24);
			Send_Data((void *)(&MotorOut[0]),8);
			Send_Byte('E');
#else

			Send_Byte('I');
			Send_Data((void *)(&Sensors_Latest[0]),12);
			Send_Data((void *)(&AnglePitch),4);
			Send_Data((void *)(&AngleRoll),4);
			Send_Data((void *)(&CompAccZ),4);
			Send_Data((void *)(&MotorOut[0]),8);
			Send_Byte('E');
			
#endif		
			}
			
			
		} // End of ARMED & Throttle > Minimum
				
			
	}  // End of Throttle stick is NOT Down [Armed Could be True or not]
	
	if ((!IS_TX2_GOOD)) // if no signal and there is no AutoLandingMode.
	{
		ZEROMotors();
		if (IsArmed==true)
		{
			Motor_GenerateOutputSignal();	
			Disarm();	
			SystemErrorType = SET_SYS_ERR_SIGNAL; // only error if signal lost while arming
		}
		
		
		//return ; // Do nothing all below depends on TX.
	}
	
	Motor_GenerateOutputSignal();	
	
	if (bResetTCNR1_X==true)
	{
		TCNT1_X_snapshot1= 0; // reset timeout
	}
	
	
}