camera.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Robot Group Leipzig                             *
00003  *    martius@informatik.uni-leipzig.de                                    *
00004  *    fhesse@informatik.uni-leipzig.de                                     *
00005  *    der@informatik.uni-leipzig.de                                        *
00006  *    frankguettler@gmx.de                                                 *
00007  *                                                                         *
00008  *   This program is free software; you can redistribute it and/or modify  *
00009  *   it under the terms of the GNU General Public License as published by  *
00010  *   the Free Software Foundation; either version 2 of the License, or     *
00011  *   (at your option) any later version.                                   *
00012  *                                                                         *
00013  *   This program is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00016  *   GNU General Public License for more details.                          *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU General Public License     *
00019  *   along with this program; if not, write to the                         *
00020  *   Free Software Foundation, Inc.,                                       *
00021  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00022  *                                                                         *
00023  *   $Log: camera.cpp,v $
00024  *   Revision 1.14.4.2  2005/12/06 10:13:26  martius
00025  *   openscenegraph integration started
00026  *
00027  *   Revision 1.14.4.1  2005/11/14 17:37:24  martius
00028  *   moved to selforg
00029  *
00030  *   Revision 1.14  2005/11/14 12:47:36  martius
00031  *   removed printfs
00032  *
00033  *   Revision 1.13  2005/09/27 14:00:29  robot3
00034  *   printf removed
00035  *
00036  *   Revision 1.12  2005/09/27 12:22:52  robot3
00037  *   now changing camView by mouse movement really works :)
00038  *
00039  *   Revision 1.11  2005/09/27 12:11:16  robot3
00040  *   fixed bug not be able to change the camView through mouse movement
00041  *
00042  *   Revision 1.10  2005/09/27 10:49:20  robot3
00043  *   camera module rewritten, new features:
00044  *   -everytime there is a smooth move and view
00045  *   -some hacks are replaced through stable code
00046  *
00047  *   Revision 1.9  2005/09/20 10:55:14  robot3
00048  *   camera module:
00049  *   -pressing key c now centers on focused robot
00050  *   -pressing key b now moves 5.0f behind the robot
00051  *   -fixed a few bugs (nullpointer crashes etc.)
00052  *
00053  *   Revision 1.8  2005/09/02 17:20:18  martius
00054  *   advancedTV disabled
00055  *
00056  *   Revision 1.7  2005/08/23 11:41:20  robot1
00057  *   advancedFollowing mode included
00058  *
00059  *   Revision 1.6  2005/08/22 12:38:32  robot1
00060  *   -advancedTV mode implemented, early version
00061  *   -internal code optimized
00062  *   -printMode prints now the current camera mode on stdout
00063  *
00064  *   Revision 1.5  2005/08/16 10:06:48  robot1
00065  *   TV mode with horizontal centering implemented.
00066  *
00067  *   Revision 1.4  2005/08/12 11:56:46  robot1
00068  *   tiny bugfixing
00069  *
00070  *   Revision 1.3  2005/08/09 11:08:49  robot1
00071  *   following mode included
00072  *
00073  *
00074  *   Revision 1.1  2005/08/08 11:06:46  martius
00075  *   camera is a module for camera movements
00076  *   includes cleaned
00077  *
00078  *                                                                         *
00079  *                                                                         *
00080  ***************************************************************************/
00081  
00082 #include "camera.h" 
00083 #include <stdio.h>
00084 
00085 namespace lpzrobots {
00086 
00087 // #include <drawstuff/drawstuff.h>
00088 // #include "ode/ode.h" 
00089 
00090 // CameraType oldCamType;
00091 // const OdeRobot* oldRobot;
00092 
00093 // // all desired values that have to be in the end state
00094 // float desiredCamPos[3];
00095 // float desiredCamView[3];
00096 
00097 // // for camera and robot: current (read and calculated) values
00098 // float currentCamPos[3];
00099 // float currentCamView[3];
00100 // double currentRobotPos[3];
00101 // double currentRobotView[3];
00102 
00103 // // for camera and robot: old values from one timestep before
00104 // float oldCamPos[3];
00105 // float oldCamView[3];
00106 // double oldRobotPos[3];
00107 // double oldRobotView[3];
00108 
00109 
00110 // // for advanced TV mode
00111 // float maxAllowedDistance=10.0f; // enabled advanvedTV ;)
00112 // float robCamDistance;
00113 
00114 
00115 
00116 // // this is a bit faster than the compiler definition:
00117 // // #define SQUARE(x) (x)*(x)
00118 // // x is only calculated once, not twice
00119 // double SQUARE(double x) {
00120 //      return (x*x);
00121 
00122 // }
00123 
00124 // // I didn't found the math library so fast, sorry.
00125 // float ABS(float x) {
00126 //   if (x<0)
00127 //     return (x*(-1));
00128 //   else
00129 //     return x;
00130 // }
00131 
00132 // void followRobotsMove() {
00133 //      // now adjusting the desired position of the camera
00134 //      for (int i=0;i<=2;i++) {
00135 //              desiredCamPos[i]+=currentRobotPos[i]-oldRobotPos[i];
00136 //      }
00137 // }
00138 
00139 // // changes only the desiredCamView
00140 // void centerViewOnRobot() {
00141 //      // no change for z
00142 //      if ((currentRobotPos[1]-desiredCamPos[1])!=0) { // division by zero
00143 //              // calculate the horizontal angle
00144 //              desiredCamView[0]=-atan((currentRobotPos[0]-desiredCamPos[0])/
00145 //                                      (currentRobotPos[1]-desiredCamPos[1]))
00146 //                                                      /M_PI*180.0f+270.0f;
00147 //              if (desiredCamPos[1]-currentRobotPos[1]<0)
00148 //                      desiredCamView[0]+=180.0f; // we must switch
00149 //      }
00150 //      if ((currentRobotPos[2]-desiredCamPos[2])!=0) { // division by zero
00151 //              // calculate the vertical angle
00152 //              // we need dz and sqrt(dx^2+dy^2) for calculation
00153 //              desiredCamView[1]=
00154 //                      atan(
00155 //                              (sqrt(
00156 //                              SQUARE(desiredCamPos[0]-currentRobotPos[0]) +
00157 //                              SQUARE(desiredCamPos[1]-currentRobotPos[1])))
00158 //                                      /(currentCamPos[2]-currentRobotPos[2]))
00159 //                                      /M_PI*180.0f+270.0f; // TODO: normalize
00160 //      }
00161 //      // z-angle (rotation) is not adjusted
00162 // }
00163 
00164 
00165 
00166 // void getRobotPosAndView(double *pos, double *view,OdeRobot& robot) {
00167 //      Position position=robot.getPosition();
00168 //      pos[0]=position.x;
00169 //      pos[1]=position.y;
00170 //      pos[2]=position.z;
00171 //      // now the view
00172 //      for (int i=0;i<=2;i++) {
00173 //              view[i]=pos[i]-oldRobotPos[i];
00174 //         }
00175 //      // if no view can be detected, use old view!
00176 //      if (view[0]==0 && view[1]==0) {
00177 //              for (int i=0;i<=2;i++) {
00178 //                      view[i]=oldRobotView[i];
00179 //              }
00180 //      }
00181 // }
00182 
00183 // // prints the current (used) mode on stdout
00184 // void printMode(CameraType camType) {
00185 //      char* type;
00186 //      printf("Current Mode is now: ");
00187 //      switch (camType) {
00188 //              case Static:
00189 //                      type="Static";
00190 //                      break;
00191 //              case TV:
00192 //                      type="TV";
00193 //                      break;
00194 //              case advancedTV:
00195 //                      type="advancedTV";
00196 //                      break;
00197 //              case Following:
00198 //                      type="Following";
00199 //                      break;
00200 //              case advancedFollowing:
00201 //                      type="advancedFollowing";
00202 //                      break;
00203 //              default:
00204 //                      type="unknown";
00205 //      }
00206 //      printf("%s\n",type);
00207 // }
00208 
00209 // // has to be called if CameraType or the Robot has changed.
00210 // void initCamera(CameraType camType,OdeRobot& robot) {
00211 //      // getting first the position and view of robot
00212 //      getRobotPosAndView(oldRobotPos, oldRobotView, robot);
00213 //      // now getting the current angle of the camera
00214 //      dsGetViewpoint(oldCamPos,oldCamView);
00215 //      if (oldCamType!=camType)
00216 //              printMode(camType);
00217 //      if (oldRobot!=&robot) // Robot is changed
00218 //              // setting current cam values to desired values
00219 //              for (int i=0;i<=2;i++) {
00220 //                      desiredCamPos[i]=oldCamPos[i];
00221 //                      desiredCamView[i]=oldCamView[i];
00222 //              }
00223 //      // setting the new Values
00224 //      oldCamType=camType;
00225 //      oldRobot=&robot;
00226 // }
00227 
00228 // void StaticMode(OdeRobot& robot) {
00229 //      // do nothing
00230 // }
00231 
00232 // void TVMode(OdeRobot& robot) {
00233 //      centerViewOnRobot();
00234 // }
00235 
00236 // void advancedTVMode(OdeRobot& robot) {
00237 //      // check wether the camera is too far away
00238 //      robCamDistance= (sqrt(
00239 //                      SQUARE(currentCamPos[0]-currentRobotPos[0]) +
00240 //                      SQUARE(currentCamPos[1]-currentRobotPos[1])));
00241 //      if (robCamDistance>maxAllowedDistance) {
00242 //              // then the camera must get a new position, centering on position of robot
00243 //              desiredCamPos[0]=currentRobotPos[0];
00244 //              desiredCamPos[1]=currentRobotPos[1];
00245 //              desiredCamPos[2]=currentRobotPos[2]+2.0f; // must be higher than robPos...
00246 //              //              printf("I am too far away from maximum distance(%f): %f\n",maxAllowedDistance,robCamDistance);
00247 //      }
00248 //      // now do the rest of TV
00249 //      centerViewOnRobot();
00250 // }
00251 
00252 // void FollowingMode(OdeRobot& robot) {
00253 //      followRobotsMove();
00254 // }
00255 
00256 // void print3DimFloat(float vec[3]) {
00257 //      for (int i=0;i<=2;i++) {
00258 //              printf("\t%f",vec[i]);
00259 //      }
00260 // }
00261 
00262 // void moveOnRobot(OdeRobot& robot) {
00263 //   //printf("moveOnRobot is now called!\n");
00264 //   // now getting the current angle of the camera
00265 //      for (int i=0;i<=1;i++) {
00266 //              desiredCamPos[i]=currentRobotPos[i];
00267 //      }
00268 //      desiredCamPos[2]=currentRobotPos[2]+2.0f;
00269 //      // center the view on the robot
00270 //      centerViewOnRobot();
00271 // }
00272 
00273 // void moveBehindRobot(OdeRobot& robot) {
00274 //   //printf("moveBehindRobot is now called!\n");
00275 //      robCamDistance=4.0f; // the distance of camera position
00276 //      // now get normalizing scalar of currentRobotView, only x and y is needed
00277 //      float n=sqrt(SQUARE(currentRobotView[0])+SQUARE(currentRobotView[1]));
00278 //      if (n>0) {
00279 //              for (int i=0;i<=1;i++)
00280 //                desiredCamPos[i]=currentRobotPos[i]-currentRobotView[i]/n*robCamDistance;
00281 //              centerViewOnRobot();
00282 //      } else { // we think this is the best
00283 //              moveOnRobot(robot);
00284 //      }
00285 // }
00286 
00287 
00288 // void advancedFollowingMode(OdeRobot& robot) {
00289 //      float n;
00290 //      // first calculate current distance and set the desired position behind the robot
00291 //      robCamDistance= (sqrt(
00292 //                      SQUARE(currentCamPos[0]-currentRobotPos[0]) +
00293 //                      SQUARE(currentCamPos[1]-currentRobotPos[1])));
00294 //      // the direction of the robot is stored in currentRobotView!
00295 //      // now get normalizing scalar of currentRobotView, only x and y is needed
00296 //      n=sqrt(SQUARE(currentRobotView[0])+SQUARE(currentRobotView[1]));
00297 //      if (n>0) { // else no calculation can be made, then do not change the camPos
00298 //              for (int i=0;i<=1;i++) {
00299 //                      // now set the camPos to robotPos-robCamDistance*robotView
00300 //                      // this is an approximation, normally a rotation is needed
00301 //                      // store it in newCamPos, so TV mode can be called unmodified
00302 //                      desiredCamPos[i]=currentRobotPos[i]
00303 //                        -currentRobotView[i]*robCamDistance/n+currentRobotView[i];
00304 //              }
00305 //      }
00306 //      // now do centering the view on robot
00307 //      centerViewOnRobot();
00308 // }
00309 
00310 
00311 // void adjustPosByMouseMove() {
00312 //      for (int i=0;i<=2;i++) {
00313 //        desiredCamPos[i]+=currentCamPos[i]-oldCamPos[i];
00314 //        //      if (oldCamPos[i]-currentCamPos[i]>0) 
00315 //        // desiredCamPos[i]=currentCamPos[i];
00316 //      }
00317 // }
00318 
00319 // void adjustViewByMouseMove() {
00320 //      for (int i=0;i<=2;i++) {
00321 //              desiredCamView[i]-=oldCamView[i]-currentCamView[i];
00322 //      }
00323 // }
00324 
00325 // void storeOldValues(float *setCamPos, float *setCamView) {
00326 //      for (int i=0;i<=2;i++) {
00327 //              oldRobotPos[i]=currentRobotPos[i];
00328 //              oldRobotView[i]=currentRobotView[i];
00329 //              oldCamPos[i]=setCamPos[i];
00330 //              oldCamView[i]=setCamView[i];
00331 //      }
00332 // }
00333 
00334 
00335 // // wrapper function
00336 // void doubleTofloatA(const double *doubleArray,float *floatArray) {
00337 //   for (int i=0;i<=2;i++) {
00338 //     floatArray[i]=doubleArray[i];
00339 //   }
00340 // }
00341 
00342 // // wrapper function
00343 // void floatTodoubleA(const float *floatArray,double *doubleArray) {
00344 //   for (int i=0;i<=2;i++) {
00345 //     doubleArray[i]=floatArray[i];
00346 //   }
00347 // }
00348 
00349 
00350 // Position smoothMove() {
00351 //      double newPos[3];
00352 //      for (int i=0;i<=2;i++) {
00353 //        if (ABS(desiredCamPos[i]-currentCamPos[i])<0.1f) {
00354 //          newPos[i]=desiredCamPos[i];
00355 //        } else
00356 //          newPos[i]=desiredCamPos[i]*0.1f+currentCamPos[i]*0.9f;
00357 //      }
00358 //      return Position(newPos);
00359 // }
00360 
00361 // // normalizes the angle
00362 // float normalize360(float angle) {
00363 //   float result=angle;
00364 //     while (result>=360.0f)
00365 //       result-=360.0f;
00366 //     while (result<0.0f)
00367 //       result+=360.0f;
00368 //     return result;
00369 // }
00370 
00371 // // normalizes the angle
00372 // double normalize360(double angle) {
00373 //   double result=angle;
00374 //     while (result>=360.0f)
00375 //       result-=360.0f;
00376 //     while (result<0.0f)
00377 //       result+=360.0f;
00378 //     return result;
00379 // }
00380 
00381 // // normalizes the angle of all 3 components
00382 // void normalize360vec3(float *angle) {
00383 //   for (int i=0;i<=2;i++) {
00384 //     angle[i]=normalize360(angle[i]);
00385 //   }
00386 // }
00387 
00388 // // normalizes the angle of all 3 components
00389 // void normalize360vec3(double *angle) {
00390 //   for (int i=0;i<=2;i++) {
00391 //     angle[i]=normalize360(angle[i]);
00392 //   }
00393 // }
00394 
00395 
00396 // Position smoothView() {
00397 //      double newView[3];
00398 //      normalize360vec3(desiredCamView);
00399 //      normalize360vec3(currentCamView);
00400 //      for (int i=0;i<=2;i++) {
00401 //        if (ABS(desiredCamView[i]-currentCamView[i])<0.2f) {
00402 //          newView[i]=desiredCamView[i];
00403 //        } else if (ABS(desiredCamView[i]-currentCamView[i])>180.0f) {
00404 //          // we must first transform the angles into linear gradient space (+180 degrees)
00405 //          // then make a backtransformation (-180 degrees)
00406 //          newView[i]=normalize360(desiredCamView[i]+180.0f)*0.1f
00407 //            +normalize360(currentCamView[i]+180.0f)*0.9f-180.0f;
00408 //        normalize360(newView[i]);
00409 //        } else { // use normal sliding
00410 //          newView[i]=desiredCamView[i]*0.1f+currentCamView[i]*0.9f;
00411 //        }
00412 //      }
00413 //      return Position(newView);
00414 // }
00415 
00416 
00417 // void moveCamera( CameraType camType,OdeRobot& robot) {
00418 //      // first look if someone is changed
00419 //      // only otherwise change the camera position and/or view.
00420 //      if (oldCamType!=camType || &robot!=oldRobot)
00421 //              initCamera(camType,robot);
00422 //      else {
00423 //              // first get all needed values
00424 //              // getting first the position and view of robot
00425 //              getRobotPosAndView(currentRobotPos,currentRobotView, robot);
00426 //              // now getting the current position and angle of the camera
00427 //              dsGetViewpoint(currentCamPos,currentCamView);
00428 //              // now compute
00429 //              // calculate the adjusted new settings from mouse movement
00430 //              adjustPosByMouseMove();
00431 //              adjustViewByMouseMove();
00432 //              // now adjust the desired values through the camera modes
00433 //              switch (camType) {
00434 //                      case Static:
00435 //                              StaticMode(robot);
00436 //                              break;
00437 //                      case advancedTV:
00438 //                              advancedTVMode(robot);
00439 //                              break;
00440 //                      case TV:
00441 //                              TVMode(robot);
00442 //                              break;
00443 //                      case Following:
00444 //                              FollowingMode(robot);
00445 //                              break;
00446 //                      case advancedFollowing:
00447 //                              advancedFollowingMode(robot);
00448 //                              break;
00449 //              }
00450 //              // now execute :)
00451 //              float move[3];
00452 //              float view[3];
00453 //              doubleTofloatA(smoothMove().toArray(),move);
00454 //              doubleTofloatA(smoothView().toArray(),view);
00455 //              dsSetViewpoint(move,view);
00456 //              // now store the current (set) values to old values
00457 //              storeOldValues(move,view);
00458 //      }
00459 // }
00460 
00461 }

Generated on Tue Apr 4 19:05:03 2006 for Robotsystem from Robot Group Leipzig by  doxygen 1.4.5