/* $Id$ * * This file is a part of jPapaBench providing a Java implementation * of PapaBench project. * Copyright (C) 2010 Michal Malohlava <michal.malohlava_at_d3s.mff.cuni.cz> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ package papabench.core.simulator.devices.impl; import papabench.core.autopilot.data.Position3D; import papabench.core.autopilot.devices.GPSDevice; import papabench.core.simulator.devices.SimulatedDevice; import papabench.core.simulator.model.FlightModel; import papabench.core.utils.MathUtils; import papabench.core.utils.StatsUtils; /** * Simulated GPS device implementation. It provides data computed according last airplane position and state. * * @author Michal Malohlava * */ public class SimulatorGPSDeviceImpl implements GPSDevice, SimulatedDevice { private float altitude; private float climb; private float course; private float east; private float north; private int utmEast; private int utmNorth; private float speed; private int mode; private float tow; // time private boolean positionAvailable = false; /* last values */ private Position3D lastPosition; private float lastSpeed = 0; private float lastCourse = 0; private float lastClimb = 0; private float lastTime = 0; public void init() { lastPosition = new Position3D(0, 0, 0); positionAvailable = false; mode = 1 << 5; } public void reset() { } public void update(FlightModel flightModel) { update(flightModel.getState().getPosition(), /*FIXME*/ 125, flightModel.getState().getTime()); } // FIXME should reflects initial UTM position of airplane : now initial position is (0,0). The same for altitude protected void update(Position3D position, float groundAltitude, float time) { float dt = time - lastTime; if (dt > 0f) { float dx = position.x - lastPosition.x; float dy = position.y - lastPosition.y; lastSpeed = (float) (Math.sqrt(dx*dx + dy*dy) / dt); lastCourse = MathUtils.normalizeRadAngle((float) (Math.PI - Math.atan2(dy, dx))); lastClimb = (position.z - lastPosition.z) / dt; } // FIXME following code transforms (x,y) position to UTM position reflecting initial position // let utm0 = utm_of WGS84 !pos0 in // let utm = utm_add utm0 (x, y) in // let wgs84 = of_utm WGS84 utm lastPosition.x = position.x; lastPosition.y = position.y; lastPosition.z = position.z; lastTime = time; // update state of GPSDevice altitude = groundAltitude + position.z; course = (float) (lastCourse < 0 ? lastCourse + MathUtils.TWO_PI : lastCourse); climb = climbNoise(lastClimb); speed = lastSpeed; east = position.x; north = position.y; // utm position ignored this.positionAvailable = true; } private float climbNoise(float climb) { return climb + StatsUtils.randNormalDistribution(0.9f, 0.1f); } public float getAltitude() { return altitude; } public float getClimb() { return climb; } public float getCourse() { return course; } public float getEast() { return east; } public int getMode() { return mode; } public float getNorth() { return north; } public float getSpeed() { return speed; } public float getTow() { return tow; } public int getUtmEast() { return utmEast; } public int getUtmNorth() { return utmNorth; } public boolean isPositionAvailable() { return positionAvailable; } }