-- main.lua
-- ****** Comment *****************************************************
-- Revision: 4.2
-- Issued  : Aug.5, 2025
-- Auther  : Tanzai
-- Contents: This script controlls a plugin, "H3-22S_launch" on X-Plane 11 
--           or X-Plane 12.
--           This Plugin shall be stored in /plugins/ folder under airplane
--           folder.
-- Notice 1: The package may be redistributed for non commercial purposes
--           only; derivatives MAY NOT be redistributed.
-- Notice 2: Do not resize X-Plane window during flight to prevent incorrrect
--           display. At any rate you can restore the window by pressing a menu 
--           "Reload theCurrent Airplane (Skip Art Reload)" under "Developer".
-- *******************************************************************
-- Custom slider setting
--   showPart[10] = Boosters smoke/jet display    0:hide  1:show
--   showPart[11] = Stage 1 jet display           0:hide  1:show
--   showPart[12] = Stage 2 jet display           0:hide  1:show

setAircraftPanelRendering(false)
set3DRendering(false)
setInteractivity(false)

-- Subwindow setting  ------------------------------------------
winW = globalPropertyi("sim/graphics/view/window_width")
winH = globalPropertyi("sim/graphics/view/window_height")

Map = contextWindow {
	position 		= { 0, 0, 1198, 509},
	noResize 		= true,
	visible 		= true,
	noBackground 	= true,
	layer			= SASL_CW_LAYER_FLOATING_WINDOWS,
	noDecore 		= true,
	noMove 			= true,
	components 		= { rootMap{position={0, 0, 1198, 509},},},
					  }

popup = contextWindow {
	position 		= {(get(winW)/2)-500, (get(winH)/2)+180, 1000, 100},
	noResize 		= true,
	visible 		= true,
	noBackground 	= true,
	layer			= SASL_CW_LAYER_FLOATING_WINDOWS,
	noDecore 		= true,
	noMove 			= true,
	components 		= {simPopup{position={0, 0, 1000, 100},},},
					  }
					  
starter = contextWindow {
    position		= { 0, get(winH)-80, 1200, 80},
    noResize		= false,
    visible			= true,
	proportional	= false,
    noBackground    = true,
	layer			= SASL_CW_LAYER_FLOATING_WINDOWS,
    noDecore        = true,
    noMove          = true,
    components		= {simBoard  {position={0, 0,1200, 75},},
 					   simLiftoff{position={0, 0,1200, 34},},
					  },}

-- Variables setting  ---------------------------------------------------
defineProperty("startIsOn", 0)
defineProperty("simStage", 0)
defineProperty("resetIsOn", 0)
defineProperty("mapIsOn", 0)
defineProperty("t3", 0)
defineProperty("targetH", 400)            -- target orbit height (km)
defineProperty("headPsi", 90)             -- flight direction (North is 0, deg)
defineProperty("Note1", " ")              -- 飛行中画面の説明書き
defineProperty("crrVelo", 0.0)            -- 現在速度(m/s)
defineProperty("endVelo", 0.0)
defineProperty("curLon", 0.0)             -- 現在経度(度)
defineProperty("curLat", 0.0)             -- 現在緯度(度)
defineProperty("dispH", 0.0)              -- 表示高度

addSearchResourcesPath ( moduleDirectory .. "/configuration/" )
hideBooster1= createGlobalPropertyi("H3/hide/Booster1",   0) -- 1:hide
hideBooster2= createGlobalPropertyi("H3/hide/Booster2",   0) -- 1:hide
hideFirstS  = createGlobalPropertyi("H3/hide/FirstStage", 0) -- 1:hide
hideSolar   = createGlobalPropertyi("H3/hide/Solar",  0)     -- 1:hide
hideFairingL= createGlobalPropertyi("H3/hide/FairingSL",  0) -- 1:hide
hideFairingR= createGlobalPropertyi("H3/hide/FairingSR",  0) -- 1:hide
hideSecondS = createGlobalPropertyi("H3/hide/SecondStage",0) -- 1:hide
points1= createGlobalPropertyfa("H3/root/points1" , 50 )     -- points(x1,y1,..)
points2= createGlobalPropertyfa("H3/root/points2" , 50 )     -- points(x1,y1,..)
LauncherObj = sasl.loadObject( "H3_Launch_pad.obj" )
H3_coundown = sasl.al.loadSample ( "H3_countdown.wav" )
H3_sound = sasl.al.loadSample ( "H3_sound.wav" )
as = globalPropertyf("sim/flightmodel/position/true_airspeed") -- m/s 速度
elv = globalPropertyd("sim/flightmodel/position/elevation")    -- n, m 高度
lat = globalPropertyd("sim/flightmodel/position/latitude") -- n, deg 緯度
lon = globalPropertyd("sim/flightmodel/position/longitude")-- n, deg 経度
quat = globalPropertyfa("sim/flightmodel/position/q")      -- y, 四元数
vx = globalPropertyf("sim/flightmodel/position/local_vx")  -- y, m/s 東が正
vy = globalPropertyf("sim/flightmodel/position/local_vy")  -- y, m/s 真上が正
vz = globalPropertyf("sim/flightmodel/position/local_vz")  -- y, m/s 南が正
planeX = globalPropertyd("sim/flightmodel/position/local_x") -- 東を正
planeY = globalPropertyd("sim/flightmodel/position/local_y") -- 真上が正
planeZ = globalPropertyd("sim/flightmodel/position/local_z") -- 南が正
vRoll = globalPropertyf("sim/flightmodel/position/P") -- ロ-ル回転速度(deg/s)
vPitch= globalPropertyf("sim/flightmodel/position/Q") -- ピッチ回転速度(deg/s)
vYaw  = globalPropertyf("sim/flightmodel/position/R") -- ヨー回転速度(deg/s)
sim_time = globalPropertyf("sim/operation/misc/frame_rate_period")
Booster_release = createGlobalPropertyf("H3/Booster/release", 0)
First_release   = createGlobalPropertyf("H3/First/release", 0)
Second_release  = createGlobalPropertyf("H3/Second/release", 0)
Fairing_release = createGlobalPropertyf("H3/Fairing/release", 0)
showPart = globalPropertyia("sim/cockpit2/switches/custom_slider_on")
simTime = sasl.createTimer()
oldVelo = {0.0,0.0,0.0}
xFactor = {}
yFactor = {}
vFactor = {}
fuelMass = {}
iniMass = {}
totalMass = {}
points1 = {}
points2 = {} 

-- Function to set rocket parameters  -----------------------------
function setRocket()
	if get(targetH) == 100 then                    -- 目標高度(km)
		-- Spec   Booster   1st    2nd  Orbiter
		tStart  ={   0  ,   95  ,  135 ,  0   }  -- 燃焼開始時間(整数) sec
		firingT ={  90  ,   35  ,  370 ,  0   }  -- 燃焼時間(整数) sec
		angThe  ={-0.174532,  -1.39626, -1.39626, -1.55334}  -- 迎角 rad
-- 				  -10.0    ,  -80.0   , -80.0   , -89.0      -- 迎角 deg
	elseif get(targetH) == 200 then              -- 目標高度(km)
		-- Spec    Booster  1st      2nd  Orbiter
		tStart  ={   0  ,   95  ,  125 ,  0   }  -- 燃焼開始秒 sec
		firingT ={  90  ,   25  ,  370 ,  0   }  -- 燃焼時間 sec
		angThe  ={-0.174532,-0.78539,-0.78539,-1.55334}  -- 迎角 deg
--			      -10.0,  -45.0, -45.0, -89.0
	elseif get(targetH) == 400 then              -- 目標高度(km)
		-- Spec    Booster   1st     2nd  Orbiter
		tStart  ={   0  ,  110  , 202  ,  0   }  -- 燃焼開始時間(整数) sec
		firingT ={ 105  ,   80  , 370  ,  0   }  -- 燃焼時間(整数) sec
		angThe  ={-0.174532,-0.69813,-1.04719,-1.55334}  -- 迎角 deg
-- 				  -10.0    ,  -40.0   , -55.0   , -89.0      -- 迎角 deg
	elseif get(targetH) == 600 then              -- 目標高度(km)
		-- Spec    Booster   31st     2nd  Orbiter
		tStart  ={   0  ,  110  , 190  ,  0   }  -- 燃焼開始時間(整数) sec
		firingT ={ 105  ,   70  , 370  ,  0   }  -- 燃焼時間(整数) sec
		angThe  ={-0.174532,-0.43633,-0.78539,-1.55334}  -- 迎角 deg
--				  -10.0,  -25.0, -45.0, -89.0
	elseif get(targetH) == 800 then                -- 目標高度(km)
		-- Spec    Booster   1st     2nd  Orbiter
		tStart  ={   0  ,  110  , 256  ,  0   }  -- 燃焼開始時間(整数) sec
		firingT ={ 105  ,   95  , 370  ,  0   }  -- 燃焼時間(整数) sec
		angThe  ={-0.174532,-0.34906,-0.52359,-1.55334}  -- 迎角 deg
--				  -10.0,  -20.0, -30.0, -89.0
	end
	-- 最初の6秒間は迎角90°となります。
	-- Boost終了からFirst点火まで5秒以上開けること。
	-- Firstの燃焼時間は12秒以上の事。
	-- First終了からSecond点火まで5秒以上開けること。
	-- Second燃焼中に高度がtargetHを超えたらに迎角を0°に変更する。
	-- Second燃焼中に速度がtargetVを超えたら停止する。
	-- 燃焼時間(firingT)の上限設定は、firingT={ 105, 153, 370, 0 }

	-- Spec    Booster   1st     2nd  Orbiter
	gLsp    ={ 2279.3, 4165.0, 4390.4,  0.0 }  -- 有効排気速度(=g*Lsp) m/s
	dryMass ={   37.4,   12.5,    3.0,  3.0 }  -- 空筐重量 ton
	fuelRate={  1.082, 0.7092, 0.03108, 0.0 }  -- 燃料消費速度 ton/sec

	for m = 1,4 do
		fuelMass[m] = fuelRate[m] * firingT[m]
		iniMass[m] = dryMass[m] + fuelMass[m]
	end
	totalMass[1] = iniMass[1] + iniMass[2] + iniMass[3] + iniMass[4]
	totalMass[2] = iniMass[2] + iniMass[3] + iniMass[4]
	totalMass[3] = iniMass[3] + iniMass[4]
end

-- -------  Other functions  ----------------------------------------------
function setOrient()
	psRad = math.rad(get(headPsi)/2)                                 -- rad 方向
	q0 = math.cos(psRad)*math.cos(pitchThe/2)
	q1 = -math.sin(psRad)*math.sin(pitchThe/2)
	q2 = math.cos(psRad)*math.sin(pitchThe/2)
	q3 = math.sin(psRad)*math.cos(pitchThe/2)
	set(quat, {q0,q1,q2,q3})
end

function setSpeed(n)                 -- Setting speed by Tsiolkovsky's equation
	psRad = math.rad(get(headPsi))                                 -- rad 方向
	xFactor[n] =-math.sin(pitchThe) * math.sin(psRad)
	yFactor[n] = math.sin(pitchThe) * math.cos(psRad)
	vFactor[n] = math.cos(pitchThe)
	-------------
	massRatio= 1.0 - fuelMass[n]*(get(t3)-tStart[n])/firingT[n]/totalMass[n]
--
--   speedDrag = cd * a * psl * exp(-beta*h) * V^2 /2
--	cd = 1.2                                       抵抗係数 (ジェミニは1.55)
--  a = 21.237                                     機体正面面積(m2) (ジェミニは4.143)
--	Psl = 1.225                                    海面空気密度(kg/m3)
--	Beta = 1/6.7                                   スケール高度の逆数(1/km)
--	speedDrag = 15.6 * exp(-h/6.7) * V^2 
--
	deltaVelo= gLsp[n]*math.log(1/massRatio) - 15.6/math.exp(get(elv)/6700)*oldVelo[n]^2
	vInX = (oldVelo[n] + deltaVelo) * xFactor[n]         -- 南北方向の係数
	vInZ = (oldVelo[n] + deltaVelo) * yFactor[n]         -- 東西方向の係数
	vInY = (oldVelo[n] + deltaVelo) * vFactor[n] - 9.8   -- 垂直方向係数、重力を加味する
	set(vx, vInX)
	set(vy, vInY)
	set(vz, vInZ)
	vDelta = (vInX^2 + vInY^2 + vInZ^2)^0.5
	set(crrVelo, vDelta)                                 -- crrVelo: 速度m/s
end

function setFreeFall(n)                                  -- Setting free fall speed
	vInY = vInY - 9.8                                    -- 重力を加味
	set(vy, vInY)
	vDelta = (vInX^2 + vInY^2 + vInZ^2)^0.5
	set(crrVelo, ( oldVelo[n] + vDelta ))                -- crrVelo: 1秒毎の速度
end

function stayRocketThere()
	set(vx, 0.0)
	set(vy, 0.0)
	set(vz, 0.0)
end

function stopRotation()
	set(vRoll, 0.0)
	set(vPitch, 0.0)
	set(vYaw, 0.0)
end

function trimEndD(valD)
	if valD > 180 then valD = valD - 360 end
	if valD < -180 then valD = valD + 360 end
	return valD
end

function trimEndR(valR)
	if valR > math.pi then valR = valR - 2*math.pi end
	if valR < -math.pi then valR = valR + 2*math.pi end
	return valR
end

function getOrbParam(LonD, LatD, PsiD)                     -- PsiD = 真東を0度とする方位角
	latRad = math.rad(LatD)                                         -- 緯度β(rad)
	orbRad = math.atan(math.tan(latRad)/math.sin(math.rad(PsiD)))   -- ω(rad)
	incRad = math.asin(math.sin(latRad)/math.sin(orbRad))           -- 軌道面傾斜角i(rad)
	lonRad = math.atan(math.tan(orbRad)*math.cos(incRad))           -- 経度α rad
	
	if LatD > 0.0 then                    -- 北半球 
		if PsiD == 0.0 then               -- 傾き零
			orbRad = math.pi/2
			lonRad = math.pi/2
		end
	else                                  -- 南半球 
		if PsiD == 0.0 then               -- 傾き零
			orbRad = -math.pi/2
			lonRad = -math.pi/2
		end
	end
		
	orbRad = trimEndR(orbRad)
	RAAN = LonD - math.deg(lonRad)
	lonRad = trimEndR(lonRad)
	return orbRad, incRad, lonRad, RAAN                 -- ω rad, 傾斜角i, 経度α, RAAN
end

function getLonLat(orbR, incR, RA)
	newLat = math.asin(math.sin(orbR)*math.sin(incR))         -- β
	alfa = math.deg(math.atan(math.tan(orbR)*math.cos(incR)))
	
	if orbR < -math.pi/2 then
		alfa = alfa - 180
	elseif orbR > math.pi/2 then
		alfa = alfa + 180
	end

	newLat = math.deg(newLat)
	newLon = trimEndD(RA + alfa)
	return newLon, newLat
end	

function getRootMap(Lon, Lat, orbR, incR, RA, delayOR, delayLD)
	delay1 = 0                                    -- サンプル毎の緯度の遅れ角 deg
	delay2 = 0                                    -- マップ線分毎の進み角を含む軌道面内角ω rad
	
	points1[1] = Lon
	points1[2] = Lat
 	points2[1] = 0
	points2[2] = 0
	for i = 3, 50, 2 do
		delay1 = delay1 + delayLD
		orbR = orbR + delayOR
		orbR = trimEndR(orbR)
		newLon,newLat = getLonLat(orbR, incR, RA)
		points1[i] = newLon - delay1
		points1[i+1] = newLat
	end
	
	for j = 1, 50, 2 do
		points1[j]   = 599 + points1[j]*598/180            -- 経度α
		points1[j+1] = 212 + points1[j+1]*304/90           -- 緯度β
	end
	
	endVal = points1[1]
	for j = 1, 50, 2 do
		if points1[j] >= endVal then              -- 最初の点と同じ半球
			pxi = points1[j]
			pyi = points1[j+1]
  			points2[j]   = 0
 			points2[j+1] = 0
 			delay2 = delay2 + delayOR             -- サンプル毎の遅れ角
		else
			points2[j]   = points1[j] - delay2    -- 経度α
 			points2[j+1] = points1[j+1]           -- 緯度β
			points1[j]   = pxi
			points1[j+1] = pyi
		end
	end
	
	for i = 50, 1, -2 do
		if points2[i] ~= 0 then
			pxii = points2[i-1]
			pyii = points2[i]
		else
			points2[i-1] = pxii
			points2[i] = pyii
		end
	end
end

function iniValSet()              -- Function to set initial value
	t2 = -6
	set(headPsi, 90)              -- 出発点で進行方向を真北(0°)から右回りに墓有った角度deg
	pitchThe = 0                  -- 直立時を0radとする迎角(モデルが水平の時は-1.57079となる)
	set(Note1, "")
	set(showPart, 0, 10)          -- No show Boosters smoke/jet
	set(showPart, 0, 11)          -- No show Stage 1 jet
	set(showPart, 0, 12)          -- No show Stage 2 jet
	set(vx, 0.0)
	set(vz, 0.0)
	vInX = 0.0
	vInY = 0.0
	vInH = 0.0
	Action1 = 0
	Action2 = 0
	Action3 = 0
	Action4 = 0
	Action5 = 0
	Action6 = 0
	Action7 = 0
	Action8 = 0
	set(Booster_release, 0)
	set(First_release, 0)
	set(Second_release, 0)
	set(Fairing_release, 0)
	set(hideBooster1,0)
	set(hideBooster2,0)
	set(hideFirstS,  0)
	set(hideSolar, 1)
	set(hideFairingL,0)
	set(hideFairingR,0)
	set(hideSecondS, 0)
	state = 0
	state1 = 0
	state2 = 0
	state3 = 0
	state4 = 0
	count1 = 0                 -- for print out counter
	count2 = 0                 -- for setting at reaching targetspeed
	mapIsOn = 0
	nLine = 24                 -- マップの軌道線分の数
end

-- Main control ----------------------------------------------------
set(simStage, 0)
set(startIsOn, 0)
set(resetIsOn, 0)
iniValSet()                                     -- Initialize values
setRocket()                                     -- Set rocket parameters

function update()
	if get(simStage) == 0 then                    -- 軌道設定画面
		stayRocketThere()
		set(curLon, get(lon))                     -- 経度 deg
		set(curLat, get(lat))                     -- 緯度 deg
		mapIsOn = 1
		
		state2 = state2 + get(sim_time)
		if state2 >= 1 then
			state2 = 0
			orbRad,incRad,lonRad,RAAN=getOrbParam(get(curLon),get(curLat),90-get(headPsi))
			targetVkm = (398600.5/(get(targetH)+6378.14))^0.5         -- 速度 km/s
			tCycle = 2*math.pi*(get(targetH)+6378.14)/targetVkm/60    -- 周期 min
			delayLonD = 360*tCycle/1440/nLine      -- マップの1線分毎の軌道面角ωの遅れ角(deg)
			delayOrbR = 2*math.pi/nLine            -- サンプル周期1秒毎に地球が回転する角(rad)
			getRootMap(get(curLon),get(curLat),orbRad,incRad,RAAN,delayOrbR,delayLonD)
		end

		if get(startIsOn) == 1 then                 -- "Liftoff" pressed 
			iniLon = get(lon)
			iniLat = get(lat)
			iniElv = get(elv)
			iniPsi = get(headPsi)
			orbRad,incRad,lonRad,RAAN=getOrbParam(iniLon, iniLat, 90-iniPsi)
			---------
			set(simStage, 1)
			set(startIsOn, 0)
			iniValSet()                             -- Initialize values
			setRocket()                             -- Set rocket parameters
			
		elseif get(resetIsOn) == 1 then             -- "Reset" pressed 
			sasl.commandOnce( viewSet )
			set(startIsOn, 0)
			set(resetIsOn, 0)
			sasl.placeUserAtLocation(iniLat,iniLon,iniElv,iniPsi,0.0)
			iniValSet()                              -- Initialize values
			setRocket()                              -- Set rocket parameters
		end
	end
	
	-----------  Control during launching  -----------
	if get(simStage) == 1 then                      -- Simulation starts
		state3 = state3 + get(sim_time)
		if state3 >= 1 then                           -- 1秒毎に以下を実施
			state3 = 0
			t2 = t2 + 1
			set(t3, t2)
			set(curLon, get(lon))                   -- 経度 deg
			set(curLat, get(lat))                   -- 緯度 deg
			set(dispH, math.floor(get(elv)/1000))
			
			if t2 == -5 then
				sasl.al.playSample( H3_coundown )
			elseif t2 < tStart[1] then
				stayRocketThere()
				oldVelo[1] = 0.0
				set(Note1, "Countdown starts")
			elseif t2 == tStart[1] then             -- Booster fires
				tEnd1 = tStart[1] + firingT[1]
				set(vx, 0.0)
				set(vz, 0.0)
				sasl.al.playSample( H3_sound )
				set(showPart, 1, 10)                -- Boosters smoke/jet on
				set(Note1, "Lifting up by Boosters")
			elseif t2 < tStart[1] + 6 then          -- Booster firing
				setSpeed(1)
				set(vx, 0.0)
				set(vz, 0.0)	
			elseif t2 == tStart[1] + 6 then
				setSpeed(1)
				Action1 = 1                        -- Tilt rocket a little	
			elseif t2 < tEnd1 then                 -- Booster firing
				setSpeed(1)
			elseif t2 == tEnd1 then                -- Booster stops
				setSpeed(1)
				set(showPart, 0, 10)               -- Boosters smoke/jet off
				Action2 = 1                 -- Booster release animation starts 5s
			elseif t2 < tStart[2] then
				setFreeFall(1)
				set(Note1, "Boosters released")
 			elseif t2 == tStart[2] then            -- 1st Stage starts
				tEnd2 = tStart[2] + firingT[2]
				oldVelo[2] = get(crrVelo)
				set(showPart, 1, 11)               -- Stage 1 jet on
				Action3 = 1                    -- Change pitch and heading in 10s
				Action4 = 1                    -- Animation of Fairing release 20s
				set(Note1, "1st Stage engine running")
			elseif t2 < tEnd2 then
				setSpeed(2)
			elseif t2 == tEnd2 then                -- 1st Stage ends
				setSpeed(2)
				set(showPart, 0, 11)               -- Stage 1 jet off
				Action5 = 1                        -- animation Stage 1 release
			elseif t2 < tStart[3] then
				setFreeFall(2)
				set(Note1, "1st Stage engine cutoff")
			elseif t2 == tStart[3] then            -- 2nd Stage starts
				tEnd3 = tStart[3] + firingT[3]
				oldVelo[3] = get(crrVelo)
				Action6 = 1                        -- Stage 2 change pitch in 4s
				set(showPart, 1, 12)               -- Stage 2 jet on
				set(Note1, "2nd Stage engine running")
			elseif t2 < tEnd3 then
				setSpeed(3)
				if get(dispH) > get(targetH) then     -- Reach target height
					set(simStage, 2)
					Action7 = 1             -- Stage 2 change pitchThe to level	
					set(Note1, "Reached target height, Increasing speed")
					--
					set(endVelo,(398600.5/(get(dispH)+6378.14))^0.5) -- 速度km/s
					cycle = 2*math.pi*(get(dispH)+6378.14)/get(endVelo) -- 周期sec
				end
			elseif t2 >= tEnd3 then         -- 2nd Stage stops out of orbit
				set(headPsi, iniPsi)
				setSpeed(3)
				set(Note1, "Failed to reach target height and speed")
				set(simStage, 3)                         -- Simulation ends
				state3 = 0
			end
		end
		---------------------------------
		if Action1 == 1 then                           -- Tilt rockedt a little
			state = state + get(sim_time)
			pitchThe = state*angThe[1]
			if state >= 1 then
				Action1 = 0
				state = 0
			end
		end

		if Action2 == 1 then                               -- Remove Boosters
			state = get(Booster_release) + get(sim_time)/5
			set(Booster_release, state)
			if state >= 1 then
				set(hideBooster1,1)
				set(hideBooster2,1)
				Action2 = 0 
				state = 0
			end
		end
	
		if Action3 == 1 then            -- Stage 1 Change pitchThe and headPsi
			state = state + get(sim_time)/5
			if state <= 1 then
				pitchThe = angThe[1] + state*(angThe[2]-angThe[1])
				set(headPsi, 90 + state*(iniPsi-90))
			else	
				Action3 = 0
				state = 0	
			end
		end

		if Action4 == 1 then                       -- Animation of Fairing release
			state1 = get(Fairing_release) + get(sim_time)/10
			set(Fairing_release, state1)
			if state1 >= 1 then
 				set(hideFairingL,1)
 				set(hideFairingR,1)
				Action4 = 0
				state1 = 0
			end
		end
		
		if Action5 == 1 then              -- animation of Stage 1
			state = get(First_release) + get(sim_time)/5
			set(First_release, state)
			if state >= 1 then
				set(hideFirstS,  1)                  -- 1st Stage removed
				Action5 = 0
				state = 0
			end
		end
	
		if Action6 == 1 then                         -- Change pitchThe of 2nd Stage
			state = state + get(sim_time)/4
			pitchThe = angThe[2] + state*(angThe[3]-angThe[2])
			if state >= 1 then
				Action6 = 0
				state = 0
			end
		end
		setOrient()
		stopRotation()
	end

	---------  increasing speed on orbit  ---------------- 
	if get(simStage) == 2 then                      -- Simulation starts
		setSpeed(3)
		if get(crrVelo) > get(endVelo)*1000 then
			set(Note1, "Orbiting on target height and speed")
			set(simStage, 3)                 -- Simulation ends
			set(showPart, 0, 12)             -- Stage 2 jet off
			--
			vRad = get(crrVelo)/(get(dispH)+6378.14)/1000  -- 角速度(rad/s)
			preLon = get( get(lon) )
			preLat = get( get(lat) )
			orbRad,incRad,lonRad,RAAN=getOrbParam(preLon,preLat,90-iniPsi)
			delay3 = 0                       -- 軌道を周回中の地球自転による遅れの累積値
			Action8 = 1                      -- Release 2nd Stage
			state3 = 0
		end
		
		state3 = state3 + get(sim_time)
		if state3 >= 1 then                           -- 1秒毎に以下を実施
			state3 = 0
			t2 = t2 + 1
			set(t3, t2)
			set(curLon, get(lon))                       -- 経度 deg
			set(curLat, get(lat))                       -- 緯度 deg
			set(dispH, math.floor(get(elv)/1000))
		end
		setOrient()
		stopRotation()
	end

	---------  Control during orbiting  ---------------- 
	if get(simStage) == 3 then                        -- Orbit starts
		orbRad = orbRad + vRad*get(sim_time)
		if orbRad > math.pi then orbRad = orbRad - 2*math.pi end
		newLon,newLat = getLonLat(orbRad, incRad, RAAN)
		newLon = newLon - 0.00416666666*get(sim_time)
		if newLon >  180 then newLon = newLon - 360 end
		if newLon < -180 then newLon = newLon + 360 end
		newX,newY,newZ = sasl.worldToLocal(newLat,newLon,get(dispH)*1000)
		set( planeX, newX )
		set( planeY, get(dispH)*1000 )
		set( planeZ, newZ )
		--
		state3 = state3 + get(sim_time)
		if state3 >= 1 then                           -- 秒毎に以下を実施
			state3 = 0
			t2 = t2 + 1
			set(t3, t2)
			set(curLon, get(lon))                       -- 経度 deg
			set(curLat, get(lat))                       -- 緯度 deg
			set(dispH, math.floor(get(elv)/1000))
			print("vx=", get(vx), "vy=", get(vy), "vz=", get(vz))
		end
	end
	
	if Action7 == 1 then                          -- Change pitchThe to level
		state4 = state4 + get(sim_time)/2
		pitchThe = angThe[3] + state4*( -1.55334 - angThe[3])
		setOrient()
		if state4 >= 1 then
			Action7 = 0
			state4 = 0
			set(vy, 0.0)
		end
	end
	
	if Action8 == 1 then                                     -- Remove 2nd
		state = get(Second_release) + get(sim_time)/4
		set(Second_release, state)
		if state >= 1 then
			set(hideSecondS, 1)
			set(hideSolar, 0)
			Action8 = 0
			state = 0
		end
	end
end

-- default view setting  ------------------------------------------------
viewSet = sasl.findCommand ( "sim/view/circle" )
function onModuleInit ()
	sasl.commandOnce( viewSet )
end

function onAirportLoaded()
	sasl.commandOnce( viewSet )
	iniX = get(planeX)
	iniY = get(planeY)
	iniZ = get(planeZ)
	Launcher = sasl.createInstance(LauncherObj)
	sasl.setInstancePosition(Launcher,iniX,iniY,iniZ,0,90,0)
end

components={ simBoard{}, simLiftoff{}, simPopup{}, rootMap{},}