00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Image/OpenCVUtil.H"
00039
00040 #include "Component/ModelManager.H"
00041 #include "Devices/DeviceOpts.H"
00042 #include "GUI/XWinManaged.H"
00043 #include "Raster/GenericFrame.H"
00044 #include "Raster/Raster.H"
00045 #include "Component/ModelManager.H"
00046 #include "Devices/DeviceOpts.H"
00047 #include "GUI/XWindow.H"
00048 #include "Image/DrawOps.H"
00049 #include "Image/CutPaste.H"
00050 #include "Image/Image.H"
00051 #include "Image/Pixels.H"
00052 #include "Image/MathOps.H"
00053 #include "Neuro/EnvVisualCortex.H"
00054 #include "Media/FrameSeries.H"
00055 #include "Media/MediaOpts.H"
00056 #include "Transport/FrameInfo.H"
00057 #include "Raster/GenericFrame.H"
00058 #include "Raster/Raster.H"
00059 #include "Util/Timer.H"
00060 #include "Util/log.H"
00061 #include "Util/MathFunctions.H"
00062 #include "Learn/Bayes.H"
00063 #include "Learn/BackpropNetwork.H"
00064 #include "Envision/env_image_ops.h"
00065 #include "Neuro/BeoHeadBrain.H"
00066 #include "Image/ShapeOps.H"
00067 #include "Devices/BeeSTEM.H"
00068 #include "rutz/shared_ptr.h"
00069
00070
00071 #include <ctype.h>
00072 #include <deque>
00073 #include <iterator>
00074 #include <stdlib.h>
00075 #include <string>
00076 #include <vector>
00077 #include <map>
00078
00079 #define UP 98
00080 #define DOWN 104
00081 #define RIGHT 102
00082 #define LEFT 100
00083
00084
00085 #define THRUSTER_UP_LEFT 1
00086 #define THRUSTER_UP_RIGHT 3
00087 #define THRUSTER_UP_BACK 2
00088 #define THRUSTER_FWD_RIGHT 4
00089 #define THRUSTER_FWD_LEFT 0
00090
00091
00092 XWinManaged *xwin;
00093 Timer timer;
00094 Image<PixRGB<byte> > disp;
00095 byte SmaxVal = 0;
00096 int smap_level = -1;
00097
00098 bool debug = 0;
00099 bool init_points = true;
00100
00101
00102
00103 class BeeSTEM_PID_Listener : public BeeSTEMListener
00104 {
00105 public:
00106 BeeSTEM_PID_Listener(nub::soft_ref<BeeSTEM> &b) :
00107 itsBeeStem(b)
00108 {
00109 pidHeading.reset(new PID<float>(0.1, 0, 0, -100.0, 100.0));
00110 pidPitch.reset(new PID<float>(0.1, 0, 0, -100.0, 100.0));
00111 pidRoll.reset(new PID<float>(0.1, 0, 0, -100.0, 100.0));
00112
00113 thrust_h_left = 0;
00114 thrust_h_right = 0;
00115 thrust_v_left = 0;
00116 thrust_v_right = 0;
00117 thrust_v_back = 0;
00118
00119 target_heading = 0;
00120 }
00121
00122 virtual ~BeeSTEM_PID_Listener()
00123 { }
00124
00125
00126 void setTargetHeading(int _h) {
00127 target_heading = _h;
00128 heading_enable = true;
00129
00130
00131 thrust_h_left = 0;
00132 thrust_h_right = 0;
00133 thrust_v_left = 0;
00134 thrust_v_right = 0;
00135 thrust_v_back = 0;
00136 }
00137
00138 void setTargetPitch(int _h) {
00139 target_pitch = _h;
00140 pitch_enable = true;
00141
00142
00143 thrust_h_left = 0;
00144 thrust_h_right = 0;
00145 thrust_v_left = 0;
00146 thrust_v_right = 0;
00147 thrust_v_back = 0;
00148 }
00149
00150 void disableHeadingTarget() {
00151 heading_enable = false;
00152 }
00153
00154 void disablePitchTarget() {
00155 pitch_enable = false;
00156 }
00157
00158 void setPrintOnly(bool b) {
00159 print_only = b;
00160 }
00161
00162 int getPos()
00163 {
00164 return itsCurrentPos;
00165
00166 }
00167
00168
00169
00170 virtual void event(const BeeSTEMEventType t, const unsigned char dat1,
00171 const unsigned char dat2)
00172 {
00173 LDEBUG("Event: %d dat1 = %d, dat2 = %d", int(t), dat1, dat2);
00174
00175 switch(t) {
00176
00177 case COMPASS_HEADING_EVENT:
00178 {
00179 int heading = (unsigned int)dat1*2;
00180 itsCurrentPos = heading;
00181 if (pidHeading.is_valid())
00182 {
00183 float rot = 100*pidHeading->update(target_heading, (float)heading);
00184 thrust_h_left+=(int)rot;
00185 thrust_h_right-=(int)rot;
00186
00187 if(!print_only) {
00188
00189
00190 }
00191 }
00192
00193 }
00194 break;
00195 case COMPASS_PITCH_EVENT:
00196 {
00197 if(pitch_enable)
00198 {
00199 int pitch = (signed char)dat1;
00200 if (pidPitch.is_valid())
00201 {
00202 float pitchCorr = 100*pidPitch->update(target_pitch, (float)pitch);
00203 thrust_v_left += (int)pitchCorr;
00204 thrust_v_right -= (int)pitchCorr;
00205 itsBeeStem->setMotor(THRUSTER_UP_RIGHT, (int)thrust_v_right);
00206 itsBeeStem->setMotor(THRUSTER_UP_LEFT, (int)thrust_v_left);
00207 }
00208 }
00209 }
00210 break;
00211 case COMPASS_ROLL_EVENT:
00212 {
00213 int roll = (signed char)dat1;
00214 roll++;
00215 }
00216 break;
00217 case ACCEL_X_EVENT: break;
00218 case ACCEL_Y_EVENT: break;
00219 case INT_PRESS_EVENT: break;
00220 case EXT_PRESS_EVENT:
00221
00222 break;
00223 case TEMP1_EVENT: break;
00224 case TEMP2_EVENT: break;
00225 case DIG_IN_EVENT: break;
00226 case ADC_IN_EVENT: break;
00227 case MOTOR_A_CURR_EVENT: break;
00228 case MOTOR_B_CURR_EVENT: break;
00229 case MOTOR_C_CURR_EVENT: break;
00230 case MOTOR_D_CURR_EVENT: break;
00231 case MOTOR_E_CURR_EVENT: break;
00232 case ECHO_REPLY_EVENT: LINFO("BeeSTEM Echo Reply Recieved."); break;
00233 case RESET_EVENT: LERROR("BeeSTEM RESET occurred!"); break;
00234 case SW_OVERFLOW_EVENT: LERROR("BeeSTEM Software Overflow!"); break;
00235 case FRAMING_ERR_EVENT: LERROR("BeeSTEM Framing Error!"); break;
00236 case OVR_ERR_EVENT: LERROR("BeeSTEM Hardware Overflow!"); break;
00237 case HMR3300_LOST_EVENT: break;
00238 case ACCEL_LOST_EVENT: break;
00239 case TEMP1_LOST_EVENT: break;
00240 case TEMP2_LOST_EVENT: break;
00241
00242 case ESTOP_EVENT: break;
00243 case UNRECOGNIZED_EVENT: break;
00244 case BAD_OUT_CMD_SEQ_EVENT: LERROR("BeeSTEM Reports a Bad Command Sequence!"); break;
00245 case BAD_IN_CMD_SEQ_EVENT: break;
00246 case RESET_ACK_EVENT: LINFO("BeeSTEM Acknowledges Reset Request"); break;
00247 case NO_EVENT: break;
00248 default: LERROR("Unknown event %d received!", int(t)); break;
00249
00250 }
00251
00252
00253
00254 }
00255 private:
00256 nub::soft_ref<BeeSTEM> itsBeeStem;
00257 int heading;
00258 bool heading_enable, print_only;
00259 bool pitch_enable;
00260 int target_pitch;
00261
00262 rutz::shared_ptr< PID<float> > pidHeading;
00263 rutz::shared_ptr< PID<float> > pidPitch;
00264 rutz::shared_ptr< PID<float> > pidRoll;
00265 rutz::shared_ptr< PID<float> > pidDepth;
00266
00267 signed int thrust_h_left, thrust_h_right, thrust_v_left, thrust_v_right, thrust_v_back;
00268
00269 int target_heading;
00270 int itsCurrentPos;
00271 };
00272
00273
00274 void display(Image<PixRGB<byte> > &img);
00275
00276 int main(int argc, const char **argv)
00277 {
00278
00279 ModelManager *mgr = new ModelManager("SeaBee Interface");
00280
00281 nub::ref<InputFrameSeries> ifs(new InputFrameSeries(*mgr));
00282 mgr->addSubComponent(ifs);
00283
00284 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(*mgr));
00285 mgr->addSubComponent(ofs);
00286
00287 nub::soft_ref<BeeSTEM> b(new BeeSTEM(*mgr,"BeeSTEM", "BeeSTEM", "/dev/ttyS1"));
00288 mgr->addSubComponent(b);
00289
00290
00291
00292
00293
00294
00295
00296 mgr->exportOptions(MC_RECURSE);
00297
00298 mgr->setOptionValString(&OPT_InputFrameSource, "V4L2");
00299 mgr->setOptionValString(&OPT_FrameGrabberMode, "YUYV");
00300 mgr->setOptionValString(&OPT_FrameGrabberDims, "1024x576");
00301
00302 mgr->setOptionValString(&OPT_FrameGrabberFPS, "30");
00303
00304
00305 if (mgr->parseCommandLine(argc, argv, "", 0, 0) == false) return(1);
00306
00307
00308 Dims imageDims(320,240);
00309
00310 xwin = new XWinManaged(Dims(imageDims.w()*2,imageDims.h()*2+20),
00311 -1, -1, "SeaBee interface");
00312 disp = Image<PixRGB<byte> >(imageDims.w(),imageDims.h()+20, ZEROS);
00313
00314
00315 mgr->start();
00316
00317
00318 ifs->startStream();
00319
00320 timer.reset();
00321
00322
00323 while(1) {
00324
00325 const FrameState is = ifs->updateNext();
00326 if (is == FRAME_COMPLETE)
00327 break;
00328
00329
00330 GenericFrame input = ifs->readFrame();
00331 if (!input.initialized())
00332 break;
00333 Image<PixRGB<byte> > frontImg = rescale(input.asRgb(), 320, 240);
00334
00335 ofs->writeRGB(frontImg, "input", FrameInfo("Copy of input", SRC_POS));
00336
00337
00338 int key = xwin->getLastKeyPress();
00339
00340 int speed = 100;
00341 switch(key)
00342 {
00343 case 38:
00344 b->setMotor(2,-1 * speed);
00345 b->setMotor(1,-1 * speed);
00346 b->setMotor(3,-1 * speed);
00347 break;
00348 case 52:
00349 b->setMotor(2,speed );
00350 b->setMotor(1,speed );
00351 b->setMotor(3,speed );
00352 break;
00353 case LEFT:
00354 b->setMotor(0, speed);
00355 b->setMotor(4, -1 * speed);
00356 break;
00357 case RIGHT:
00358 b->setMotor(0, -1 * speed);
00359 b->setMotor(4, speed);
00360 break;
00361 case UP:
00362 b->setMotor(0, -1 * speed);
00363 b->setMotor(4, -1 * speed);
00364 break;
00365 case DOWN:
00366 b->setMotor(0, speed);
00367 b->setMotor(4, speed);
00368 break;
00369 case 65:
00370 b->setMotor(0,0);
00371 usleep(1000);
00372 b->setMotor(1,0);
00373 usleep(1000);
00374 b->setMotor(2,0);
00375 usleep(1000);
00376 b->setMotor(3,0);
00377 usleep(1000);
00378 b->setMotor(4,0);
00379 usleep(1000);
00380 break;
00381
00382 default:
00383 break;
00384 }
00385 display(frontImg);
00386
00387 }
00388
00389
00390
00391 mgr->stop();
00392
00393
00394 return 0;
00395 }
00396
00397 void display(Image<PixRGB<byte> > &img)
00398 {
00399 static int avgn = 0;
00400 static uint64 avgtime = 0;
00401
00402
00403
00404 xwin->drawImage(img, 0, 0);
00405
00406
00407 avgn++;
00408 avgtime += timer.getReset();
00409 if (avgn == 20)
00410 {
00411 avgtime = 0;
00412 avgn = 0;
00413 }
00414
00415
00416
00417
00418
00419
00420
00421 }
00422