Package lejos.robotics.proposal

Source Code of lejos.robotics.proposal.DeadReckonerPoseProvider

package lejos.robotics.proposal;

import lejos.geom.Point;
import lejos.robotics.MoveListener;
import lejos.robotics.Movement;
import lejos.robotics.MovementProvider;
import lejos.robotics.Pose;
import lejos.robotics.localization.PoseProvider;

/*
* WARNING: THIS CLASS IS SHARED BETWEEN THE classes AND pccomms PROJECTS.
* DO NOT EDIT THE VERSION IN pccomms AS IT WILL BE OVERWRITTEN WHEN THE PROJECT IS BUILT.
*/

/**
* A PoseProvider that keeps track of coordinates using dead reckoning, by monitoring Pilot movements.
*
* Question: What about a robot that is helped along with a Compass? Should the compass go in a DeadReckoner
*  constructor, or a Pilot constructor? The PoseProvider seems more logical but Lawrie wants it to only
*  accept a Pilot.
*
* Provisional name: DeadReckonerPoseProvider
* Alternate names:  DeadReckonerPoseProvider, DeadReckoner, OrienteeringPoseProvider, OdometryPoseProvider
*
*/
public class DeadReckonerPoseProvider implements MoveListener, PoseProvider {
  private float x = 0, y = 0, heading = 0;
  private float angle0, distance0;
  MovementProvider mp;
  boolean current = true;
 
  /**
   * Internally, the constructor  listens to movements from the Pilot. This allows it to keep
   * track of all vector movements made.
   *
   * @param mp the movement provider
   */
  public DeadReckonerPoseProvider(MovementProvider mp) {
    mp.addMoveListener(this);
  }
   
  public Pose getPose() {
    if (!current) updatePose(mp.getMovement());
    return new Pose(x,y,heading);
  }

  public void movementStarted(Movement event, MovementProvider mp) {
      angle0 = 0;
      distance0 = 0;
      current = false;
      this.mp = mp;;
  }

  public void movementStopped(Movement event, MovementProvider mp) {
    updatePose(event);
  }
 
  /*
   * Update the pose with the movement that has occurred since the
   * movementStarted even
   */
  private void updatePose(Movement event) {
    float angle = event.getAngleTurned() - angle0;
    float distance = event.getDistanceTraveled() - distance0;
        double dx = 0, dy = 0;
        double headingRad = (Math.toRadians(heading));
        //MovementType type = event.getMovementType();
       
        if (Math.abs(angle) > .5) { // rotate or arc
            double turnRad = Math.toRadians(angle);
            double radius = event.getArcRadius(); // zero for rotate
            if (radius != 0) {
              dy = radius * (Math.cos(headingRad) - Math.cos(headingRad + turnRad));
              dx = radius * (Math.sin(headingRad + turnRad) - Math.sin(headingRad));
            }
        } else if (Math.abs(distance) > .01) { // travel
            dx = (distance) * (float) Math.cos(headingRad);
            dy = (distance) * (float) Math.sin(headingRad);
        }
       
        heading = normalize(heading + angle); // keep angle between -180 and 180
        x += dx;
        y += dy;
        angle0 = event.getAngleTurned();
        distance0 = event.getDistanceTraveled();
        current = !event.isMoving();   
  }

    /*
     * returns equivalent angle between -180 and +180
     */
    private float normalize(float angle) {
        float a = angle;
        while (a > 180) {
            a -= 360;
        }
        while (a < -180) {
            a += 360;
        }
        return a;
    }
   
    public void setPosition(Point p) {
      x = p.x;
      y = p.y;
      current = true;
    }
   
    void setHeading(float heading) {
      this.heading = heading;
      current = true;
    }
}
TOP

Related Classes of lejos.robotics.proposal.DeadReckonerPoseProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.