public void ApplyEngineAction(EngineActions action) { var tip = new[] { Math.Sin(this.transform.Rotation), Math.Cos(this.transform.Rotation) }; var side = new[] { -tip[1], tip[0] }; var dispersion = new[] { ((this.random.NextDouble() * 2) - 1) / LunarConstants.SCALE, ((this.random.NextDouble() * 2) - 1) / LunarConstants.SCALE }; if (action == EngineActions.Main) { var power = 1f; var ox = tip[0] * (4 / LunarConstants.SCALE + 2 * dispersion[0]) + side[0] * dispersion[1]; var oy = -tip[1] * (4 / LunarConstants.SCALE + 2 * dispersion[0]) - side[1] * dispersion[1]; var impulsePosition = new Vector2(this.transform.Position.X + (float)ox, this.transform.Position.Y + (float)oy); var impulsePower = new Vector2((float)-ox * LunarConstants.MAIN_ENGINE_POWER * power, (float)oy * LunarConstants.MAIN_ENGINE_POWER * power); this.body.ApplyLinearImpulse(impulsePower, impulsePosition, true); this.particlesEmitter.CreateParticle(3.5f, impulsePosition, power, impulsePower * -1f); } if (action == EngineActions.Left || action == EngineActions.Right) { var power = 1f; var direction = (int)action - 2; var ox = tip[0] * dispersion[0] + side[0] * (3 * dispersion[1] + direction * LunarConstants.SIDE_ENGINE_AWAY / LunarConstants.SCALE); var oy = -tip[1] * dispersion[0] - side[1] * (3 * dispersion[1] + direction * LunarConstants.SIDE_ENGINE_AWAY / LunarConstants.SCALE); var impulsePosition = new Vector2(this.transform.Position.X + (float)ox - (float)tip[0] * 17 / LunarConstants.SCALE, this.transform.Position.Y + (float)oy + (float)tip[1] * LunarConstants.SIDE_ENGINE_HEIGHT / LunarConstants.SCALE); var impulsePower = new Vector2((float)-ox * LunarConstants.SIDE_ENGINE_POWER * power, (float)oy * LunarConstants.SIDE_ENGINE_POWER * power); this.body.ApplyLinearImpulse(impulsePower, impulsePosition, true); this.particlesEmitter.CreateParticle(3.5f, impulsePosition, power, impulsePower * -1f); } }
public void ApplyEngineAction(EngineActions action) { var rotation = Quaternion.Identity; var enginePenalty = 0f; switch (action) { case EngineActions.None: break; case EngineActions.YawPositive: this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Up * rotationImpulse); enginePenalty -= 0.03f; break; case EngineActions.YawNegative: this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Up * -rotationImpulse); enginePenalty -= 0.03f; break; case EngineActions.RollPositive: this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Forward * -rotationImpulse); enginePenalty -= 0.03f; break; case EngineActions.RollNegative: this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Forward * rotationImpulse); enginePenalty -= 0.03f; break; case EngineActions.Main: var impulse = 0.7f * this.transform.LocalTransform.Up; this.shipBody.ApplyImpulse(impulse); this.dust.MainEngine = true; enginePenalty -= 0.3f; break; case EngineActions.PitchPositive: this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Left * rotationImpulse); enginePenalty -= 0.03f; break; case EngineActions.PitchNegative: this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Left * -rotationImpulse); enginePenalty -= 0.03f; break; default: break; } if (this.numActions < MaxActions) { this.actionsQueue[this.numActions++] = action; } }
private ActionResult GetActionResult(EngineActions action) { var observation = this.GetUpdatedObservation(); var gameOver = this.LanderBodyCollided; // || !this.LanderAwake return(new ActionResult { Done = gameOver, Observation = observation, Reward = 0f }); }
private ActionResult GetActionResult(EngineActions action) { var observation = new Observation { PosX = this.landerBody.Transform2D.Position.X / ((LunarConstants.VIEWPORT_W / LunarConstants.SCALE) / 2), PosY = (LunarConstants.VIEWPORT_H - this.landerBody.Transform2D.Position.Y) / (LunarConstants.VIEWPORT_H / LunarConstants.SCALE), VelX = this.landerBody.LinearVelocity.X * ((LunarConstants.VIEWPORT_W / LunarConstants.SCALE) / 2) / LunarConstants.FPS, VelY = this.landerBody.LinearVelocity.Y * ((LunarConstants.VIEWPORT_H / LunarConstants.SCALE) / 2) / LunarConstants.FPS, Angle = this.landerBody.RigidBody.Angle, AngVel = 20f * this.landerBody.AngularVelocity / LunarConstants.FPS, LeftContact = this.leftCollided ? 1f : 0f, RightContact = this.rightCollided ? 1f : 0f }; var reward = 0d; var shaping = -100 * Math.Sqrt(observation.PosX * observation.PosX + observation.PosY * observation.PosY) - 100 * Math.Sqrt(observation.VelX * observation.VelX + observation.VelY * observation.VelY) - 100 * Math.Abs(observation.Angle) + 10 * observation.LeftContact + 10 * observation.LeftContact; if (this.previousShaping != null) { reward = shaping - this.previousShaping.Value; } this.previousShaping = shaping; reward -= (action == EngineActions.Main ? 1 : 0) * 0.3; reward -= (action == EngineActions.Left || action == EngineActions.Right ? 1 : 0) * 0.3; var done = false; if (this.gameOver || Math.Abs(observation.PosX) >= 1) { done = true; reward = -100; } if (!this.landerBody.Awake) { done = true; reward = 100; } return(new ActionResult { Done = done, Observation = observation, Reward = (float)reward }); }
private void OnActionReceived(object sender, EngineActions e) { this.shipComponent.ApplyEngineAction(e); }