zoukankan      html  css  js  c++  java
  • 【不务正业】太空工程师自动导航v1.0 beta

    //By dudujerry
    //2021.4.17
    //自动导航 v1.0 beta

    Vector3D TARGET = new Vector3D(158267.95,-25453.61,-60794.93);
    
    List<IMyThrust> _thrusts = new List<IMyThrust>();
    List<IMyShipController> _shipControls = new List<IMyShipController>();
    List<IMyCameraBlock> _camera = new List<IMyCameraBlock>();
    List<IMyGyro> _gyros = new List<IMyGyro>();
    IMyShipController _cockpit;
    
    Vector3D _MaxAngleAcceleration;
    Vector3D _InitAngleVelocity;
    Vector3D targetThrustPower = new Vector3D();
    Vector3D t = new Vector3D();
    
    bool _dam;
    int debug = 0;
    double debug2 = 0;
    int _state;//0代表正在寻找位置,1代表降落
    double _maxThrust;
    float _height;
    bool _flag = false;
    
    float bac = 0,fr = 0,lef = 0 ,rig = 0,up = 0,down = 0;
    
    const string COCKPIT_NAME = "MainCockpit";
    const double MAX_DISTANCE = 2000;
    const double GYRO_I = 30;
    const double GYRO_D = 30;
    const double MAX_ERROR = 0.1;
    const double MAX_ANGLE_ERROR = 0.5;
    const double MAX_VELOCITY_ERROR = 0.5;
    const double GYRO_MULTEXTRA = 2;
    const int GYRO_T = 30;
    const float _ELE_MAX_ERROR = 2;
    const float _MIN_VELOCITY = 2;
    
    const float MAX_VELOCITY = 100;
    
    const double THRUST_I = 30;
    const double THRUST_D = 30;
    const int THRUST_T = 30;
    const double THRUST_MULTEXTRA = 1;
    
    const double _extra = 100;
    
    class PIDClass{
    		
    	public double getPID(double d){
    		
    		d_data.Add(d);
    		
    		if(d_data.Count == 1){
    			d_data.Add(d);
    		}
    		
    		if(d_data.Count > T){
    			d_data.Remove(d_data[0]);
    		}
    		double sum_d = 0;
    		foreach(double i in d_data){
    			sum_d += i;
    		}
    		
    		double fir = d + 1/I*(sum_d/d_data.Count) + D*(d_data[d_data.Count - 1] - d_data[d_data.Count - 2]);
    		
    		if(P2 == 0 || (fir >= 0 && P2 > 0))
    			return P * fir; //输出结果
    		else if(fir < 0 && P2 > 0){
    			return P2*fir;
    		}
    		return 0;
    	}
    	
    	public void setMultiplier(int t,double p,double i,double d){
    		T = t;
    		P = p;
    		I = i;
    		D = d;
    	}
    	
    	public void setExtraMultiplier(double p2){
    		P2 = p2;
    	}
    	
    	public PIDClass(int t,double p,double i,double d){
    		T = t;
    		P = p;
    		I = i;
    		D = d;
    	}
    		
    	private int T = 30; //周期,这个周期不是公式中的时间间隔T,而是储存累加结果的周期
    	private double P = 0.0001; //比例系数
    	private double I = 10; //积分系数
    	private double D = 50; //微分系数
    	private double P2 = 0;
    	
    	private List<double> d_data = new List<double>();
    };
    PIDClass gyroPIDX,gyroPIDY,gyroPIDZ;
    PIDClass thrustPIDX,thrustPIDY,thrustPIDZ;
    PIDClass thrustPIDY2,thrustPIDY3,thrustPIDZ2;
    
    PIDClass VthrustPIDX,VthrustPIDY,VthrustPIDZ;
    PIDClass VthrustPIDY2,VthrustPIDY3,VthrustPIDZ2;
    PIDClass VthrustPIDX4,VthrustPIDY4,VthrustPIDZ4;
    
    void PrintVector3D(Vector3D v){
    	Echo("X="+Math.Round(v.X,4).ToString());
    	Echo("Y="+Math.Round(v.Y,4).ToString());
    	Echo("Z="+Math.Round(v.Z,4).ToString());
    }
    
    public void AddVector(Vector3D addvector,IMyShipController cockpit,List<IMyThrust> thrusts){
    	
    	float ShipMass = cockpit.CalculateShipMass().PhysicalMass;
    	
    	//MatrixD refLookAtMatrix = MatrixD.CreateLookAt(new Vector3D(),cockpit.WorldMatrix.Forward, cockpit.WorldMatrix.Up);
    	//addvector = Vector3D.TransformNormal(addvector,refLookAtMatrix);
    	
    	addvector = addvector*ShipMass;
    	
    	double totalG = addvector.Length() ;
    	
    	
    	double totalthrust = 0;//debug
    	foreach(var thrust in thrusts){
    		thrust.ThrustOverride = 0;
    		thrust.ThrustOverridePercentage = 0;
    		var maxthrust = thrust.MaxEffectiveThrust;
    		thrust.Enabled = false;
    		if(!thrust.IsFunctional){
    			continue;
    		}
    		switch (cockpit.WorldMatrix.GetClosestDirection(thrust.WorldMatrix.Backward))
    		{
    			
               //设定推力
    			case Base6Directions.Direction.Backward:
    				
    				thrust.ThrustOverridePercentage=(targetThrustPower.Z>0)?(float)targetThrustPower.Z:0;
    				thrust.Enabled = (targetThrustPower.Z>0)?true:false;
    				if(addvector.Z > 0 && !_dam ){
    					thrust.Enabled = true;
    					
    					float oldth = (float)thrust.ThrustOverride;
    					if(maxthrust <addvector.Z + thrust.ThrustOverride){
    						thrust.ThrustOverride = maxthrust;
    						addvector.Z -= maxthrust - oldth;
    					}
    					else{
    						thrust.ThrustOverride += (float)addvector.Z;
    						addvector.Z = 0;
    						
    					}
    					
    				}
    				
    			break;
    			case Base6Directions.Direction.Forward:
    				
    				thrust.ThrustOverridePercentage=(targetThrustPower.Z<0)?(float)-targetThrustPower.Z:0;
    				thrust.Enabled = (targetThrustPower.Z<0)?true:false;
    				if(addvector.Z < 0&& !_dam){
    					thrust.Enabled = true;
    					float fz = (-1) * (float)addvector.Z;
    					float oldth = (float)thrust.ThrustOverride;
    					if(maxthrust <fz + oldth){
    						thrust.ThrustOverride = maxthrust;
    						addvector.Z += maxthrust - oldth;
    					}
    					else{
    						thrust.ThrustOverride += fz;
    						addvector.Z = 0;
    						
    					}
    					
    				}
    			
    			break;
    			case Base6Directions.Direction.Right:
    				
    				thrust.ThrustOverridePercentage=(targetThrustPower.X>0)?(float)targetThrustPower.X:0;
    				thrust.Enabled = (targetThrustPower.X>0)?true:false;
    				if(addvector.X > 0&& !_dam){
    					thrust.Enabled = true;
    					float oldth = (float)thrust.ThrustOverride;
    					if(maxthrust <addvector.X + oldth){
    						thrust.ThrustOverride = maxthrust;
    						addvector.X -= maxthrust - oldth;
    					}
    					else{
    						thrust.ThrustOverride += (float)addvector.X;
    						addvector.X = 0;
    						
    					}
    					
    				}
    				
    				
    			break;
    			case Base6Directions.Direction.Left:
    				
    				thrust.ThrustOverridePercentage=(targetThrustPower.X<0)?(float)-targetThrustPower.X:0;
    				thrust.Enabled = (targetThrustPower.X<0)?true:false;
    				if(addvector.X < 0&& !_dam){
    					thrust.Enabled = true;
    					float fz = (-1) * (float)addvector.X;
    					float oldth = (float)thrust.ThrustOverride;
    					if(maxthrust <fz + oldth){
    						thrust.ThrustOverride = maxthrust;
    						addvector.X += maxthrust - oldth;
    					}
    					else{
    						thrust.ThrustOverride += fz;
    						addvector.X = 0;
    						
    					}
    					
    				}
    				
    			break;
    			case Base6Directions.Direction.Up:
    				
    				thrust.ThrustOverridePercentage=(targetThrustPower.Y>0)?(float)targetThrustPower.Y:0;
    				thrust.Enabled = (targetThrustPower.Y>0)?true:false;
    				if(addvector.Y > 0&& !_dam){
    					thrust.Enabled = true;
    					float oldth = (float)thrust.ThrustOverride;
    					if(maxthrust <addvector.Y + oldth){
    						thrust.ThrustOverride = maxthrust;
    							addvector.Y -= maxthrust - oldth;
    					}
    					else{
    						
    						thrust.ThrustOverride += (float)addvector.Y;
    						addvector.Y = 0;
    						
    						int th = (int)thrust.ThrustOverride;
    						
    					}
    					
    				}
    			
    			break;
    			case Base6Directions.Direction.Down:
    				
    				thrust.ThrustOverridePercentage=(targetThrustPower.Y<0)?(float)-targetThrustPower.Y:0;
    				thrust.Enabled = (targetThrustPower.Y<0)?true:false;
    				if(addvector.Y < 0&& !_dam){
    					
    					thrust.Enabled = true;
    					float fz = (-1) * (float)addvector.Y;
    					float oldth = (float)thrust.ThrustOverride;
    					if(maxthrust <fz + oldth){
    						thrust.ThrustOverride = maxthrust;
    						addvector.Y += maxthrust - oldth;
    					}
    					else{
    						thrust.ThrustOverride += fz;
    						addvector.Y = 0;
    						
    					}						
    				}
    			break;
    		}
    		totalthrust += thrust.ThrustOverride;//debug
    
    			
    	}
    }
    
    void SetGyros(double pitch,double yaw,double roll){
    	
    	foreach(var gyro in _gyros){
    		gyro.Enabled = true;
    		gyro.GyroOverride = true;
    		//gyro.Roll = (float)roll;
    		//gyro.Pitch = (float)pitch;
    		//gyro.Yaw = (float)yaw;
    		if(pitch == 0 && yaw == 0 && roll == 0)
    			gyro.GyroOverride = false;
    		switch (_cockpit.WorldMatrix.GetClosestDirection(gyro.WorldMatrix.Backward))
    		{//正右负左,正上负下
    			case Base6Directions.Direction.Forward:
    				gyro.Pitch = (float)-pitch;
    				gyro.Yaw = (float)yaw;
    				gyro.Roll = (float)-roll;
    				break;
    			case Base6Directions.Direction.Backward:
    				gyro.Pitch = (float)pitch;
    				gyro.Yaw = (float)yaw;
    				gyro.Roll = (float)roll;
    				break;
    			case Base6Directions.Direction.Right:
    				gyro.Pitch = (float)roll;
    				gyro.Roll = (float)-pitch;
    				gyro.Yaw = (float)yaw;
    				break;
    			case Base6Directions.Direction.Left:
    				gyro.Pitch = (float)roll;
    				gyro.Roll = (float)-pitch;
    				gyro.Yaw = (float)yaw;
    				break;
    			case Base6Directions.Direction.Down:
    				gyro.Pitch = (float)pitch;
    				gyro.Roll = (float)-yaw;
    				gyro.Yaw = (float)roll;
    				break;
    			case Base6Directions.Direction.Up:
    				gyro.Roll = (float)yaw;
    				gyro.Pitch = (float)-pitch;
    				gyro.Yaw = (float)roll;
    				break;
    		}
    	}
    	
    	
    }
    
    bool InitGyros(){//测陀螺仪最大角加速度
    	if(_MaxAngleAcceleration.Length() != 0){
    		//若已经测过了,返回
    		return true;
    	}
    	
    	Vector3D angularVelocity = _cockpit.GetShipVelocities().AngularVelocity;
    	MatrixD refLookAtMatrix = MatrixD.CreateLookAt(new Vector3D(), _cockpit.WorldMatrix.Forward, _cockpit.WorldMatrix.Up);
        Vector3D meAngleVelocityToMe = Vector3D.TransformNormal(angularVelocity, refLookAtMatrix);
        //(*)-
    	double meRollAngleVelocity = meAngleVelocityToMe.Z*180/Math.PI; //当前角速度
        double mePitchAngleVelocity = meAngleVelocityToMe.X*180/Math.PI;
    	double meYawAngleVelocity = meAngleVelocityToMe.Y*180/Math.PI;
    	//得到当前帧的角速度(*)-
    	if(_InitAngleVelocity.Length() == 0){
    		_InitAngleVelocity = new Vector3D(mePitchAngleVelocity,meYawAngleVelocity,meRollAngleVelocity);
    
    		SetGyros(60,60,60);
    	}
    	else{
    		_MaxAngleAcceleration = new Vector3D((mePitchAngleVelocity - _InitAngleVelocity.X)*60,(meYawAngleVelocity - _InitAngleVelocity.Y)*60,(meRollAngleVelocity - _InitAngleVelocity.Z)*60);
    		//计算最大角加速度,由于一秒60帧所以乘60
    		//gys.SetOverride(false);
    		//gys.Yaw = gys.Pitch = 0;
    		//返回原状态(*)-
    		SetGyros(0,0,0);
    		double P = 60/(GYRO_T*(1/GYRO_I*180+GYRO_D*180))*GYRO_MULTEXTRA;
    		gyroPIDX.setMultiplier(GYRO_T,P,1/GYRO_I,GYRO_D);
    		gyroPIDY.setMultiplier(GYRO_T,P,1/GYRO_I,GYRO_D);
    		gyroPIDZ.setMultiplier(GYRO_T,P,1/GYRO_I,GYRO_D);
    	}
    	
    	return false;
    }
    
    bool gyroOperation(Vector3D target){
    	Vector3D err = new Vector3D(target.X,target.Y,target.Z);
    	if(err.Length() <= MAX_ERROR)
    		return true;
    	Vector3D nowtarget = new Vector3D(gyroPIDX.getPID(target.X),-gyroPIDY.getPID(target.Y),gyroPIDZ.getPID(target.Z));
    	SetGyros(nowtarget.X,nowtarget.Y,nowtarget.Z);
    	return false;
    }
    
    public static double TargetAngleToMe(Vector3D targetToMe,string direction){
    	targetToMe = Vector3D.Normalize(targetToMe);
    	Vector3D zForward = new Vector3D(0,0,-1);
    	
    	targetToMe.X *= -1;//SE中,前负后正,右负左正,上负下正
    	targetToMe.Y *= -1;
    	targetToMe.Z *= -1;
    	
    	if(direction == "Yaw"){
    		
    		Vector3D targetYawVector = new Vector3D(targetToMe.X,0,targetToMe.Z);
    		
    		return Math.Atan2(targetToMe.X,targetToMe.Z) * 180/Math.PI;
    		
    	}
    	else if (direction == "Pitch"){
    		Vector3D targetYawVector = new Vector3D(0,targetToMe.Y,targetToMe.Z);
    		return Math.Atan2(targetToMe.Y,targetToMe.Z) * 180/Math.PI;
    		
    		
    	}
    	else if(direction == "Roll"){
    		
    		Vector3D targetRollVector = new Vector3D(targetToMe.X,targetToMe.Y,0);
    		
    		return Math.Atan2(targetToMe.X,targetToMe.Y) * 180/Math.PI;
    		
    	}
    	
    	return 0;
    }
    
    Vector3D GetTarget(string str){
    	//解析坐标
    	return new Vector3D(0,0,0);
    }
    
    public Program()
    {
        // 构造函数,每次脚本运行时会被首先调用一次。用它来初始化脚本。
        //  构造函数是可选项,
        // 如不需要可以删除。
        // 
        // 建议这里设定RuntimeInfo.UpdateFrequency,
        // 这样脚本就不需要定时器方块也能自动运行了。
    	Runtime.UpdateFrequency = UpdateFrequency.Update1;
    	
    	_MaxAngleAcceleration = new Vector3D();
    	_InitAngleVelocity = new Vector3D();
    	debug = 0;
    	
    	gyroPIDX = new PIDClass(GYRO_T,1,1/GYRO_I,GYRO_D);
    	gyroPIDY = new PIDClass(GYRO_T,1,1/GYRO_I,GYRO_D);
    	gyroPIDZ = new PIDClass(GYRO_T,1,1/GYRO_I,GYRO_D);
    
    	
    	GridTerminalSystem.GetBlocksOfType<IMyGyro>(_gyros);
    	GridTerminalSystem.GetBlocksOfType<IMyShipController>(_shipControls);
    	GridTerminalSystem.GetBlocksOfType<IMyCameraBlock>(_camera);
    	GridTerminalSystem.GetBlocksOfType<IMyThrust>(_thrusts);
    	
    	foreach(var cam in _camera){
    		cam.EnableRaycast = true;
    	}
    	
    	bool flag = false;
    	foreach(var coc in _shipControls){
    		if(coc.CustomName == COCKPIT_NAME){
    			_cockpit = coc;
    			flag = true;
    		}
    	}
    	if(!flag) _cockpit = _shipControls[0];
    	
    	MatrixD refLookAtMatrix = MatrixD.CreateLookAt(new Vector3D(), _cockpit.WorldMatrix.Forward, _cockpit.WorldMatrix.Up);
    	
    	SetTarget();
    	/*if(_cockpit.GetNaturalGravity().Length() != 0){
    		Vector3D v3d = new Vector3D();
    		
    		_cockpit.TryGetPlanetPosition(out v3d);
    		
    		Vector3D tar_p = Vector3D.Normalize(t - v3d);
    		Vector3D me_p = Vector3D.Normalize(_cockpit.CenterOfMass - v3d);
    			
    		double angle = Math.Abs(Math.Acos(Vector3D.Dot(tar_p,me_p)/Math.Abs(tar_p.Length()*me_p.Length()))*180/Math.PI);
    		
    		v3d = Vector3D.TransformNormal(t - v3d,refLookAtMatrix);
    		_height = (float)v3d.Length();
    		
    		double ele = 0;
    		_cockpit.TryGetPlanetElevation(MyPlanetElevation.Surface,out ele);
    	}*/
    	
    	
    	
    	foreach(var thrust in _thrusts){
    		switch (_cockpit.WorldMatrix.GetClosestDirection(thrust.WorldMatrix.Backward))
    		{
    			case Base6Directions.Direction.Backward:
    				bac += thrust.MaxEffectiveThrust;
    				break;
    			case Base6Directions.Direction.Forward:
    				fr += thrust.MaxEffectiveThrust;
    				break;
    			case Base6Directions.Direction.Left:
    				lef += thrust.MaxEffectiveThrust;
    				break;
    			case Base6Directions.Direction.Right:
    				rig += thrust.MaxEffectiveThrust;
    				break;
    			case Base6Directions.Direction.Up:
    				up += thrust.MaxEffectiveThrust;
    				_maxThrust += thrust.MaxEffectiveThrust;
    				break;
    			case Base6Directions.Direction.Down:
    				down += thrust.MaxEffectiveThrust;
    				break;
    			
    		}
    	}
    	bac /= _cockpit.CalculateShipMass().PhysicalMass;
    	fr /= _cockpit.CalculateShipMass().PhysicalMass;
    	lef /= _cockpit.CalculateShipMass().PhysicalMass;
    	rig /= _cockpit.CalculateShipMass().PhysicalMass;
    	up /= _cockpit.CalculateShipMass().PhysicalMass;
    	down /= _cockpit.CalculateShipMass().PhysicalMass;
    	
    	Vector3D distance = t - _cockpit.CenterOfMass;
        t = Vector3D.TransformNormal(distance, refLookAtMatrix);
    	
    	if(distance.X < 0) distance.X = -distance.X;
    	if(distance.Y < 0) distance.Y = -distance.Y;
    	if(distance.Z < 0) distance.Z = -distance.Z;
    	
    	thrustPIDX = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*lef/((THRUST_I+THRUST_D+1)*MAX_VELOCITY),THRUST_I,THRUST_D);
    	thrustPIDY = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*down/((THRUST_I+THRUST_D+1)*MAX_VELOCITY),THRUST_I,THRUST_D);
    	thrustPIDZ = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*bac/((THRUST_I+THRUST_D+1)*MAX_VELOCITY),THRUST_I,THRUST_D);
    	
    	
    	//debug2 = angle;
    	
    	VthrustPIDX = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*MAX_VELOCITY/((THRUST_I+THRUST_D+1)*distance.X),THRUST_I,THRUST_D);
    	VthrustPIDY = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*MAX_VELOCITY/((THRUST_I+THRUST_D+1)*distance.Y),THRUST_I,THRUST_D);
    	VthrustPIDZ = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*MAX_VELOCITY/((THRUST_I+THRUST_D+1)*distance.Z),THRUST_I,THRUST_D);
    	
    	VthrustPIDX4 = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*MAX_VELOCITY/((THRUST_I+THRUST_D+1)*distance.X),THRUST_I,THRUST_D);
    	VthrustPIDY4 = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*MAX_VELOCITY/((THRUST_I+THRUST_D+1)*distance.Y),THRUST_I,THRUST_D);
    	VthrustPIDZ4 = new PIDClass(THRUST_T,10*THRUST_MULTEXTRA*MAX_VELOCITY/((THRUST_I+THRUST_D+1)*distance.Z),THRUST_I,THRUST_D);
    	
    	
    	thrustPIDX.setExtraMultiplier(20*THRUST_MULTEXTRA*rig/((1/THRUST_I+THRUST_D+1)*MAX_VELOCITY));
    	thrustPIDY.setExtraMultiplier(20*THRUST_MULTEXTRA*up/((1/THRUST_I+THRUST_D+1)*MAX_VELOCITY));
    	thrustPIDZ.setExtraMultiplier(20*THRUST_MULTEXTRA*fr/((1/THRUST_I+THRUST_D+1)*MAX_VELOCITY));
    	
    	_cockpit.DampenersOverride = false;
    	
    	
    	
    }
    
    public void Save()
    {
        // 当程序需要保存时,会发出提醒。使用这种方法可以将状态保存
        // 至内存或其他路径。此为备选项,
        // 如果不需要,可以删除。
    	foreach(var thrust in _thrusts){
    		thrust.Enabled = true;
    		thrust.ThrustOverridePercentage = 0;
    		
    	}
    	foreach(var gyro in _gyros){
    		gyro.Enabled = true;
    		gyro.GyroOverride = false;
    	}
    }
    
    void SetTarget()
    {
    	t = TARGET;
    }
    
    float GetH(float v){
    	
    	MatrixD refLookAtMatrix = MatrixD.CreateLookAt(new Vector3D(), _cockpit.WorldMatrix.Forward, _cockpit.WorldMatrix.Up);
    	
    	
    	
    	float ShipMass = _cockpit.CalculateShipMass().PhysicalMass;
    	
    	Vector3D g = _cockpit.GetNaturalGravity();
    	float totalg = (float)g.Length();
    	
    	float upv = (float)((_maxThrust - ShipMass*totalg) / (ShipMass));
    	//Echo("upv" + upv.ToString());
    	
    	
    	Vector3D V = Vector3D.TransformNormal(_cockpit.GetShipVelocities().LinearVelocity,refLookAtMatrix);
    	float vv = (float)V.Length();
    	
    	float nowv = vv;
    	float t = vv/upv;
    	float x = (float)(vv*t - 0.5*upv*t*t);
    	float totalh = x;
    	Echo("x = " + x.ToString());
    	
    	
    	return totalh + (float)_extra;
    }
    
    public void Main(string argument, UpdateType updateSource)
    {
    	
    	/*foreach(var thrust in _thrusts){
    		thrust.Enabled = true;
    		thrust.ThrustOverridePercentage = 0;
    		
    	}
    	foreach(var gyro in _gyros){
    		gyro.Enabled = true;
    		gyro.GyroOverride = false;
    	}
    	
    	return;*/
    	Echo("State="+_state.ToString());
    	
    	targetThrustPower = new Vector3D();
    	
    	if(InitGyros() == false) return;
    	_dam = _cockpit.DampenersOverride;
    	
    	MatrixD refLookAtMatrix = MatrixD.CreateLookAt(new Vector3D(), _cockpit.WorldMatrix.Forward, _cockpit.WorldMatrix.Up);
    	
    	Vector3D V = Vector3D.TransformNormal(_cockpit.GetShipVelocities().LinearVelocity,refLookAtMatrix);
    	
    	SetTarget();
    	
    	
    	Vector3D g = _cockpit.GetNaturalGravity();
    	float totalg = (float)g.Length();
    	
    
    	if(_dam == true) targetThrustPower=-Vector3D.TransformNormal(_cockpit.GetShipVelocities().LinearVelocity,refLookAtMatrix);
    	
    	if(totalg == 0)
    	{
    		t = t - _cockpit.CenterOfMass;
    	
    		
    		t = Vector3D.TransformNormal(t, refLookAtMatrix);
    		//
    
    		Vector3D tar = new Vector3D(TargetAngleToMe(t,"Pitch"),TargetAngleToMe(t,"Yaw"),0);
    		AddVector(new Vector3D(0,0,0),_cockpit,_thrusts);
    		
    		if(!gyroOperation(tar)) return;
    		
    		if(!_cockpit.DampenersOverride)targetThrustPower = new Vector3D(0,0,0);
    
    		foreach(var cam in _camera){
    			int timebeforeray = cam.TimeUntilScan(MAX_DISTANCE);
    			if(timebeforeray > 0)
    				continue;
    			MyDetectedEntityInfo info = cam.Raycast(MAX_DISTANCE,0,0);
    			if(!info.IsEmpty())
    				_cockpit.DampenersOverride = true;
    		}
    		
    
    		if(!_cockpit.DampenersOverride){
    			//Vector3D a = new Vector3D(-thrustPIDX.getPID(t.X),thrustPIDY.getPID(t.Y),thrustPIDZ.getPID(t.Z));
    			double tarv = VthrustPIDZ4.getPID(-t.Z);
    			double tara = thrustPIDZ.getPID(tarv + V.Z);
    			Vector3D a = new Vector3D(0,0,-tara);
    			Echo("tarv = " + (tarv+V.Z).ToString());
    			Echo("tara = " + tara.ToString());
    			if(Math.Abs(Vector3D.TransformNormal(_cockpit.GetShipVelocities().LinearVelocity,refLookAtMatrix).Z) >= 99)
    				a = new Vector3D(0,0,0);
    			AddVector(a,_cockpit,_thrusts);
    		}
    	}
    	else{
    		if(_flag == false) {
    			_state = -1;
    			
    			
    			Vector3D v3d = new Vector3D();
    		
    			_cockpit.TryGetPlanetPosition(out v3d);
    			
    			Vector3D tar_p = Vector3D.Normalize(t - v3d);
    			Vector3D me_p = Vector3D.Normalize(_cockpit.CenterOfMass - v3d);
    				
    			double angle = Math.Abs(Math.Acos(Vector3D.Dot(tar_p,me_p)/Math.Abs(tar_p.Length()*me_p.Length()))*180/Math.PI);
    			
    			v3d = Vector3D.TransformNormal(_cockpit.CenterOfMass - v3d,refLookAtMatrix);
    			_height = (float)v3d.Length();
    			
    			double ele = 0;
    			_cockpit.TryGetPlanetElevation(MyPlanetElevation.Surface,out ele);
    			
    			
    			thrustPIDY2 = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*down/((1/THRUST_I+THRUST_D+1)*MAX_VELOCITY),THRUST_I,THRUST_D);
    			thrustPIDY3 = new PIDClass(THRUST_T,10*THRUST_MULTEXTRA*down/((1/THRUST_I+THRUST_D+1)*MAX_VELOCITY),THRUST_I,THRUST_D);
    			//debug2 = THRUST_MULTEXTRA*down/((1/THRUST_I+THRUST_D+1)*_height);
    			thrustPIDZ2 = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*bac/((1/THRUST_I+THRUST_D+1)*MAX_VELOCITY),THRUST_I,THRUST_D);
    			
    			VthrustPIDY2 = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*MAX_VELOCITY/((1/THRUST_I+THRUST_D+1)*_height),THRUST_I,THRUST_D);
    			VthrustPIDY3 = new PIDClass(THRUST_T,30*THRUST_MULTEXTRA*MAX_VELOCITY/((1/THRUST_I+THRUST_D+1)*ele),THRUST_I,THRUST_D);
    			//debug2 = THRUST_MULTEXTRA*down/((1/THRUST_I+THRUST_D+1)*_height);
    			VthrustPIDZ2 = new PIDClass(THRUST_T,20*THRUST_MULTEXTRA*MAX_VELOCITY/((1/THRUST_I+THRUST_D+1)*angle),THRUST_I,THRUST_D);
    			
    			thrustPIDY2.setExtraMultiplier(20*THRUST_MULTEXTRA*up/((1/THRUST_I+THRUST_D+1)*MAX_VELOCITY));
    			thrustPIDY3.setExtraMultiplier(10*THRUST_MULTEXTRA*up/((1/THRUST_I+THRUST_D+1)*MAX_VELOCITY));
    			//debug2 = THRUST_MULTEXTRA*up/ele;
    			thrustPIDZ2.setExtraMultiplier(20*THRUST_MULTEXTRA*fr/((1/THRUST_I+THRUST_D+1)*MAX_VELOCITY));
    		}
    		_flag = true;
    		if(_state == -1){
    			double v = Vector3D.TransformNormal(_cockpit.GetShipVelocities().LinearVelocity,refLookAtMatrix).Length();
    			if(v > MAX_VELOCITY_ERROR) _cockpit.DampenersOverride = true;
    			else {
    				_state = 0;
    				_cockpit.DampenersOverride = false;
    			}
    			AddVector(new Vector3D(0,0,0),_cockpit,_thrusts);
    		}
    		else if(_state == 0){
    			Vector3D plantPosition;
    			_cockpit.TryGetPlanetPosition(out plantPosition);
    			
    			Vector3D tar_p = t - plantPosition;
    			Vector3D me_p = _cockpit.CenterOfMass - plantPosition;
    			
    			double angle = Math.Abs(Math.Acos(Vector3D.Dot(tar_p,me_p)/Math.Abs(tar_p.Length()*me_p.Length()))*180/Math.PI);
    			t = Vector3D.TransformNormal(t,refLookAtMatrix);
    			
    			g = Vector3D.TransformNormal(g,refLookAtMatrix);
    			Vector3D gv = new Vector3D(TargetAngleToMe(g,"Pitch")-90,TargetAngleToMe(t,"Yaw"),TargetAngleToMe(g,"Roll"));
    			AddVector(-g,_cockpit,_thrusts);
    			if(!gyroOperation(gv)) return;
    			
    			Vector3D moveg = -g;
    			double verr = VthrustPIDZ2.getPID(angle)+V.Z;
    			moveg.Z = -thrustPIDZ2.getPID(verr);//解决,双重PID
    			Echo("angle_err = "+angle.ToString());
    			Echo("velocity_err = " + verr.ToString());
    			Echo("PID outcome = " + moveg.Z.ToString());
    			
    			double z_v = V.Z;
    			if(Math.Abs(z_v) >= MAX_VELOCITY-1 && z_v * moveg.Z > 0) moveg.Z = 0;
    			
    			plantPosition = Vector3D.TransformNormal(_cockpit.CenterOfMass-plantPosition,refLookAtMatrix);
    			double vverr = VthrustPIDY2.getPID(_height - plantPosition.Length())-V.Y;
    			double y2 = thrustPIDY2.getPID(vverr);//高了为负,待测试
    			Echo("height_err = " + (_height - plantPosition.Length()).ToString());
    			Echo("verr = " + vverr.ToString());
    			Echo("PID outcome = " + y2.ToString());
    			moveg.Y += y2;
    			moveg.Y += z_v*z_v/plantPosition.Length();//***向心力
    			
    			AddVector(moveg,_cockpit,_thrusts);
    			if(angle <= MAX_ANGLE_ERROR) _state = 1;
    			
    		}
    		else if(_state == 1){
    			double v = Vector3D.TransformNormal(_cockpit.GetShipVelocities().LinearVelocity,refLookAtMatrix).Length();
    			if(v > MAX_VELOCITY_ERROR) _cockpit.DampenersOverride = true;
    			else {
    				_state = 2;
    				_cockpit.DampenersOverride = false;
    			}
    			AddVector(new Vector3D(0,0,0),_cockpit,_thrusts);
    		}
    		else if(_state == 2){
    			/* PID方法 *
    			double ele = 0;
    			_cockpit.TryGetPlanetElevation(MyPlanetElevation.Surface,out ele);
    			
    			g = Vector3D.TransformNormal(g,refLookAtMatrix);
    			Vector3D gv = new Vector3D(TargetAngleToMe(g,"Pitch")-90,0,TargetAngleToMe(g,"Roll"));
    			gyroOperation(gv);
    			
    			double verr = VthrustPIDY3.getPID(ele)-V.Y;
    			Vector3D moveg = new Vector3D(0,-thrustPIDY3.getPID(verr)-g.Y,0);//待测试***
    			Echo("ele err = " + ele.ToString());
    			Echo("tar v = " + (verr+V.Y).ToString());
    			Echo("PID outcome = " + (moveg.Y+g.Y).ToString());
    			
    			
    			
    			double y_v = Vector3D.TransformNormal(_cockpit.GetShipVelocities().LinearVelocity,refLookAtMatrix).Y;
    			
    			if(y_v > MAX_VELOCITY-1 && y_v*moveg.Y > 0) moveg.Y = 0;
    			
    			
    			AddVector(moveg,_cockpit,_thrusts);*/
    			
    			double ele = 0;
    			_cockpit.TryGetPlanetElevation(MyPlanetElevation.Surface,out ele);
    			
    			float minh = GetH((float)_cockpit.GetShipSpeed());
    			
    			g = Vector3D.TransformNormal(g,refLookAtMatrix);
    			g = Vector3D.Normalize(g);
    			Vector3D gv = new Vector3D(TargetAngleToMe(g,"Pitch")-90,0,TargetAngleToMe(g,"Roll"));
    			gyroOperation(gv);
    			
    			AddVector(new Vector3D(0,0,0),_cockpit,_thrusts);
    			
    			//Vector3D V = Vector3D.TransformNormal(_cockpit.GetShipVelocities().LinearVelocity,refLookAtMatrix);
    			
    			if(ele <= _ELE_MAX_ERROR ){
    				_state = 3;
    			}
    			else if(ele <= minh && V.Y < 0 && -V.Y >= _MIN_VELOCITY){
    				targetThrustPower = -g;
    				AddVector(new Vector3D(0,0,0),_cockpit,_thrusts);
    			}
    			
    		}
    		else if(_state == 3){
    			AddVector(new Vector3D(0,0,0),_cockpit,_thrusts);
    			g = Vector3D.TransformNormal(g,refLookAtMatrix);
    			g = Vector3D.Normalize(g);
    			Vector3D gv = new Vector3D(TargetAngleToMe(g,"Pitch")-90,TargetAngleToMe(t,"Yaw"),TargetAngleToMe(g,"Roll"));
    			gyroOperation(gv);
    		}
    	}
    		
    }
    

      

  • 相关阅读:
    react-navigation
    react
    generator-react-webpack
    安装Eclipse反编译插件(jadclipse)
    Python爬虫学习笔记3:基本库的使用
    Python爬虫学习笔记2:爬虫基础
    Python爬虫学习笔记1:request、selenium、ChromeDrive、GeckoDriver等相关依赖安装
    Python学习笔记28:面向对象进阶及 hashlib
    Python学习笔记27:反射,类的内置方法
    Python学习笔记26:封装、@property、@staticmethod和@classmethod装饰器方法、反射getattr()
  • 原文地址:https://www.cnblogs.com/dudujerry/p/14410043.html
Copyright © 2011-2022 走看看