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}