1 /* 2 * Interface to the Finch control methods 3 * 4 * Copyright (c) 2011 Derrell Lipman 5 * 6 * License: 7 * LGPL: http://www.gnu.org/licenses/lgpl.html 8 * EPL: http://www.eclipse.org/org/documents/epl-v10.php 9 */ 10 /** 11 * Get and save a new finch object, or return the existing one. 12 */ 13 _getFinch : function() 14 { 15 // Get a reference to our Finch 16 var finch = this.__finch; 17 18 // Disconnect from the finch 19 if (finch != null) 20 { 21 return finch; 22 } 23 24 // Reconnect with a new Finch object 25 try 26 { 27 // Obtain a finch object 28 this.__finch = 29 new Packages.edu.cmu.ri.createlab.terk.robot.finch.Finch(); 30 31 // Indicate success 32 return this.__finch; 33 } 34 catch (e) 35 { 36 // Some unknown error. Wrap its text in our own error 37 throw new JsonRpcError(this.constructor.Error_Finch, 38 "Finch: " + e.toString(), e); 39 } 40 }, 41 42 /** 43 * Reset the Finch by disconnecting. The next request will reconnect. 44 * 45 * @return 0, always. 46 */ 47 reset : function() 48 { 49 // If we're connected to the finch... 50 if (this.__finch != null) 51 { 52 // ... then disconnect from it, ... 53 this.__finch.quit(); 54 55 // ... and note that we're no longer connected. 56 this.__finch = null; 57 } 58 59 // Indicate success 60 return 0; 61 }, 62 63 /** 64 * Play a tone at a specified frequency for a specified duration, on the 65 * Finch's internal buzzer. 66 * 67 * Note that this is non-blocking, so a subsequent call before an initial 68 * call has completed the specified duration will stop the initial tone and 69 * begin the newly-requested one. 70 * 71 * @param frequency 72 * The frequency, in Hertz, of the tone to play. Middle C is about 73 * 262Hz. See http://www.phy.mtu.edu/~suits/notefreqs.html for 74 * frequencies of musical notes. 75 * 76 * @param duration 77 * The duration, in milliseconds, for which the tone should play. 78 * 79 * @return 80 * 0, always 81 * 82 * @throws JsonRpcError 83 */ 84 playTone : function(frequency, duration) 85 { 86 // Make him buzz 87 this._getFinch().buzz(parseInt(frequency, 10), parseInt(duration, 10)); 88 89 // Indicate success 90 return 0; 91 }, 92 93 /** 94 * Obtain the current accelerometer values. Acceleration values will be in 95 * the range [-1.5, +1.5]. When the Finch is level, the x and y values 96 * should show close to 0.0, and the z value close to +1.0 97 * 98 * @return A map containing the x, y, and z accelerometer values. 99 * @throws JsonRpcError 100 */ 101 getAccelerations : function() 102 { 103 // Get the current acceleration values 104 var accelerations = this._getFinch().getAccelerations(); 105 106 // Convert them to object format 107 return( 108 { 109 x : accelerations[0], 110 y : accelerations[1], 111 z : accelerations[2] 112 }); 113 }, 114 115 /** 116 * Get the current light sensor values. Values are in the range [0, 255] 117 * with higher values indicating more light being detected. 118 * 119 * @return A map containing the "left" and "right" light sensor values 120 * @throws JsonRpcError 121 */ 122 getLightSensors : function() 123 { 124 // Get the current light sensor values 125 var sensors = this._getFinch().getLightSensors(); 126 127 // Convert them to object format 128 return( 129 { 130 left : sensors[0], 131 right : sensors[1] 132 }); 133 }, 134 135 /** 136 * Get the current obstacle sensor values. Values are boolean, with true 137 * indicating that an obstacle is detected. 138 * 139 * @return A map containing the left and right sensor values 140 * @throws JsonRpcError 141 */ 142 getObstacleSensors : function() 143 { 144 // Get the current obstacle sensor values 145 var sensors = this._getFinch().getObstacleSensors(); 146 147 // Convert them to object format 148 return( 149 { 150 left : sensors[0], 151 right : sensors[1] 152 }); 153 }, 154 155 /** 156 * Get the current temperature sensor value. The value is measured in 157 * degrees Celsius. 158 * 159 * @return The temperature sensor value. 160 * @throws JsonRpcError 161 */ 162 getTemperature : function() 163 { 164 // Get and return the current temperature sensor value 165 return this._getFinch().getTemperature(); 166 }, 167 168 /** 169 * Get the values of all sensors. 170 * 171 * See the individual sensor methods for details of values. 172 * 173 * @return A map containing an "accelerometer" map, a "light" map, an 174 * "obstacle" map, and a "temperature" value. 175 * @throws JsonRpcError 176 */ 177 getAllSensors : function() 178 { 179 var ret = {}; 180 181 // Get a reference to our Finch 182 var finch = this._getFinch(); 183 184 // Get the current acceleration values 185 var accelerations = finch.getAccelerations(); 186 187 // Add the accelerometer values to the temp object, and add the temp 188 // object to the return object 189 ret.accelerometer = 190 { 191 x : accelerations[0], 192 y : accelerations[1], 193 z : accelerations[2] 194 }; 195 196 // Get the current light sensor values 197 var lightSensors = finch.getLightSensors(); 198 199 // Add the light sensor values to the temp object, and add the temp 200 // object to the return object 201 ret.light = 202 { 203 left : lightSensors[0], 204 right : lightSensors[1] 205 }; 206 207 // Get the current obstacle sensor values 208 var obstacleSensors = finch.getObstacleSensors(); 209 210 // Add the obstacle sensor values to the temp object, and add the temp 211 // object to the return object 212 ret.obstacle = 213 { 214 left : obstacleSensors[0], 215 right : obstacleSensors[1] 216 }; 217 218 // Get the temperature sensor value and add it to the return object 219 ret.temperature = finch.getTemperature(); 220 221 // Give 'em the whole kit and kaboodle! 222 return ret; 223 }, 224 225 /** 226 * Set Finch's beak LED to a specified color. If any color value is out of 227 * range, it is set to the closest extreme value of the legal range. 228 * 229 * @param r 230 * The intensity of red, in the range [0, 255] 231 * 232 * @param g 233 * The intensity of green, in the range [0, 255] 234 * 235 * @param b 236 * The intensity of blue, in the range [0, 255] 237 * 238 * @return 0, always 239 * @throws JsonRpcError 240 */ 241 setLED : function(r, g, b) 242 { 243 // Ensure that all intensity values are within range 244 // First red... 245 if (r < 0) 246 { 247 r = 0; 248 } 249 else if (r > 255) 250 { 251 r = 255; 252 } 253 254 // then green... 255 if (g < 0) 256 { 257 g = 0; 258 } 259 else if (g > 255) 260 { 261 g = 255; 262 } 263 264 // and finally blue. 265 if (b < 0) 266 { 267 b = 0; 268 } 269 else if (b > 255) 270 { 271 b = 255; 272 } 273 274 // Set the LED intensity 275 this._getFinch().setLED(r, g, b); 276 277 // Indicate success 278 return 0; 279 }, 280 281 /** 282 * Set the power level for each wheel. Power levels range from [-255, 255] 283 * with negative values reversing the direction the wheel turns. 284 * 285 * @param leftPower 286 * Power level to apply to the left wheel 287 * 288 * @param rightPower 289 * Power level to apply to the right wheel 290 * 291 * @return 0, always 292 * @throws JsonRpcError 293 */ 294 setWheelPower : function(leftWheelPower, rightWheelPower) 295 { 296 var leftPower = leftWheelPower; 297 var rightPower = rightWheelPower; 298 299 // If either value is out of range, map it to the closest extreme legal 300 // value. First the left wheel power... 301 if (leftPower < -255) 302 { 303 leftPower = -255; 304 } 305 else if (leftPower > 255) 306 { 307 leftPower = 255; 308 } 309 310 // ... and now the right wheel power. 311 if (rightPower < -255) 312 { 313 rightPower = -255; 314 } 315 else if (rightPower > 255) 316 { 317 rightPower = 255; 318 } 319 320 // The Finch API calls this "wheel velocity" but is implemented as wheel 321 // power. We may try to implement a velocity function based on power 322 // duty cycle, at some point. 323 this._getFinch().setWheelVelocities(leftPower, rightPower); 324 325 // Indicate success 326 return 0; 327 } 328 329