001/* This source code is released under the new BSD license, a copy of the
002 * license is in the distribution directory. */
003
004package mazerob.pc;
005
006import java.io.DataInputStream;
007import java.io.DataOutputStream;
008import java.io.IOException;
009import lejos.pc.comm.NXTCommLogListener;
010import lejos.pc.comm.NXTConnector;
011import lejos.pc.comm.NXTCommFactory;
012import lejos.robotics.RangeReadings;
013import mazerob.conn.CommandCode;
014import mazerob.conn.RemotelyControllable;
015
016/**
017 * Remotely drives an instance of {@link mazerob.nxt.Robot} through a
018 * Bluetooth connection
019 *
020 * @author Pedro I. López
021 *
022 */
023public class Robot implements RemotelyControllable {
024    /** Bluetooth NXT connector object */
025    private NXTConnector conn;
026
027    /** Data output stream object */
028    private DataOutputStream dos;
029
030    /** Data input stream object */
031    private DataInputStream dis;
032
033    /**
034     * Connects to {@link mazerob.nxt.RobotApp} through Bluetooth and
035     * sends {@link mazerob.nxt.Robot} instance configuration
036     *
037     * @param nxtName The name of the NXT
038     * @param nxtAddr The bluetooth address of the NXT
039     * @param logListener Log listener attached to the Bluetooth
040     * connection
041     * @param wheelDiameter {@code wheelDiameter} argument to {@link 
042     * mazerob.nxt.Robot#Robot}
043     * @param trackWidth {@code trackWidth} argument to {@link
044     * mazerob.nxt.Robot#Robot}
045     * @param reverse {@code reverse} argument to {@link
046     * mazerob.nxt.Robot#Robot}
047     * @param rotationSpeed {@code rotationSpeed} argument to {@link
048     * mazerob.nxt.Robot#Robot}
049     * @param translationMagnitude {@code translationMagnitude} argument to
050     * {@link mazerob.nxt.Robot#Robot}
051     * @param rotationMagnitude {@code rotationMagnitude} argument to {@link
052     * mazerob.nxt.Robot#Robot}
053     *
054     */
055    public Robot(   String nxtName,
056                    String nxtAddr,
057                    NXTCommLogListener logListener,
058                    double wheelDiameter,
059                    double trackWidth,
060                    boolean reverse,
061                    double rotationSpeed,
062                    double translationMagnitude,
063                    double rotationMagnitude) {
064
065        conn = new NXTConnector();
066        conn.addLogListener(logListener);
067
068        boolean connected = conn.connectTo(nxtName, nxtAddr,
069            NXTCommFactory.BLUETOOTH);
070
071        if (!connected) {
072            System.err.println("Failed to connect to " + nxtName +
073                " (" + nxtAddr + ")");
074            System.exit(1);
075        }
076
077        dos = new DataOutputStream(conn.getOutputStream());
078        dis = new DataInputStream(conn.getInputStream());
079
080        try {
081            dos.writeDouble(wheelDiameter);
082            dos.flush();
083            dos.writeDouble(trackWidth);
084            dos.flush();
085            dos.writeBoolean(reverse);
086            dos.flush();
087            dos.writeDouble(rotationSpeed);
088            dos.flush();
089            dos.writeDouble(translationMagnitude);
090            dos.flush();
091            dos.writeDouble(rotationMagnitude);
092            dos.flush();
093        }
094        catch(IOException e) {
095            System.out.println(e);
096            System.exit(1);
097        }
098
099    }
100
101    /**
102     * Invokes {@link mazerob.nxt.Robot#translate}
103     *
104     * @see mazerob.conn.RemotelyControllable#translate
105     *
106     */
107    public void translate(double distance) throws IOException {
108        dos.writeInt(CommandCode.TRANSLATE.ordinal());
109        dos.flush();
110        dos.writeDouble(distance);
111        dos.flush();
112    }
113
114    /** 
115     * Invokes {@link mazerob.nxt.Robot#translateForward}
116     *
117     * @see mazerob.conn.RemotelyControllable#translateForward
118     *
119     */
120    public void translateForward() throws IOException {
121        dos.writeInt(CommandCode.TRANSLATE_FORWARD.ordinal());
122        dos.flush();
123    }
124
125    /** 
126     * Invokes {@link mazerob.nxt.Robot#translateBackward}
127     *
128     * @see mazerob.conn.RemotelyControllable#translateBackward
129     *
130     */
131    public void translateBackward() throws IOException {
132        dos.writeInt(CommandCode.TRANSLATE_BACKWARD.ordinal());
133        dos.flush();
134    }
135
136    /** 
137     * Invokes {@link mazerob.nxt.Robot#rotate}
138     *
139     * @see mazerob.conn.RemotelyControllable#rotate
140     *
141     */
142    public void rotate(double angle) throws IOException {
143        dos.writeInt(CommandCode.ROTATE.ordinal());
144        dos.flush();
145        dos.writeDouble(angle);
146        dos.flush();
147    }
148
149    /** 
150     * Invokes {@link mazerob.nxt.Robot#rotateRight}
151     *
152     * @see mazerob.conn.RemotelyControllable#rotateRight
153     *
154     */
155    public void rotateRight() throws IOException {
156        dos.writeInt(CommandCode.ROTATE_RIGHT.ordinal());
157        dos.flush();
158    }
159
160    /** 
161     * Invokes {@link mazerob.nxt.Robot#rotateLeft}
162     *
163     * @see mazerob.conn.RemotelyControllable#rotateLeft
164     *
165     */
166    public void rotateLeft() throws IOException {
167        dos.writeInt(CommandCode.ROTATE_LEFT.ordinal());
168        dos.flush();
169    }
170
171    /** 
172     * Invokes {@link mazerob.nxt.Robot#scan}
173     *
174     * <p>Prints the range readings to stdout</p>
175     *
176     * @see mazerob.conn.RemotelyControllable#scan
177     *
178     */
179    public RangeReadings scan() throws IOException {
180        RangeReadings rangeValues = new RangeReadings(SCANNING_ANGLES.length);
181
182        dos.writeInt(CommandCode.SCAN.ordinal());
183        dos.flush();
184        rangeValues.loadObject(dis);
185        rangeValues.printReadings();
186        return rangeValues;
187    }
188
189    /** 
190     * Invokes {@link mazerob.nxt.Robot#end}
191     *
192     * <p>Closes Bluetooth connection</p>
193     *
194     * @see mazerob.conn.RemotelyControllable#end
195     *
196     */
197    public void end() throws IOException {
198        dos.writeInt(CommandCode.END.ordinal());
199        dos.flush();
200        dis.close();
201        dos.close();
202        conn.close();
203    }
204
205}