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 "Robots/Beobot2/Hardware/BeoGPS.H"
00039 #include "Ice/BeobotEvents.ice.H"
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 BeoGPS::BeoGPS(OptionManager& mgr,
00051 const std::string& descrName, const std::string& tagName) :
00052 RobotBrainComponent(mgr, descrName, tagName),
00053 itsSerial(new Serial(mgr)),
00054 itsOfs(new OutputFrameSeries(mgr)),
00055 itsDisplayUpdateRate(.05),
00056
00057 itsPosition(0.0,0.0,0.0),
00058 itsInitLat(-1.0),
00059 itsInitLon(-1.0),
00060 itsDispImage(512,512,ZEROS),
00061 itsCurrMessageID(0)
00062 {
00063 addSubComponent(itsSerial);
00064 addSubComponent(itsOfs);
00065 }
00066
00067
00068 BeoGPS::~BeoGPS()
00069 {
00070
00071 }
00072
00073
00074 void BeoGPS::start1()
00075 {
00076 itsSerial->configure("/dev/ttyUSB0", 115200);
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 }
00098
00099
00100 void BeoGPS::registerTopics()
00101 {
00102 registerPublisher("GPSMessageTopic");
00103 }
00104
00105
00106 void BeoGPS::evolve()
00107 {
00108
00109
00110 unsigned char cmd = 97;
00111 itsSerial->write(&cmd, 1);
00112
00113 unsigned char buffer[256];
00114 itsSerial->read(&buffer,20);
00115
00116 std::vector<unsigned char> frame(buffer+2, buffer+12);
00117
00118
00119
00120
00121
00122
00123 if(frame.size() == 10)
00124 {
00125 int latDD = frame[0];
00126 int latMM = frame[1];
00127
00128 int latMMMM = ((0x0FF & frame[2]) << 8) |
00129 ((0x0FF & frame[3]) << 0);
00130
00131 int lonDD = frame[4];
00132 int lonMM = frame[5];
00133
00134 int lonMMMM = ((0x0FF & frame[6]) << 8) |
00135 ((0x0FF & frame[7]) << 0);
00136
00137 int precision = frame[8];
00138 int satNum = frame[9];
00139
00140 double lat = latDD + (latMM * 60.0 + latMMMM * 60.0 / 10000.0) / 3600.0;
00141 double lon = lonDD + (lonMM * 60.0 + lonMMMM * 60.0 / 10000.0) / 3600.0;
00142
00143
00144 if(latDD == 34 && lonDD == 118 )
00145 {
00146 if(itsInitLat == -1.0 )
00147 {
00148
00149 LINFO("Set init GPS point Lat: %f Lon %f",lat,lon);
00150 itsInitLat = lat;
00151 itsInitLon = lon;
00152 }
00153 updatePosition(lat,lon);
00154
00155 BeobotEvents::GPSMessagePtr msg = new BeobotEvents::GPSMessage;
00156 msg->latitude = lat;
00157 msg->longitude = lon;
00158 msg->precision = precision;
00159 msg->satNum = satNum;
00160
00161 msg->RequestID = itsCurrMessageID;
00162
00163
00164 LINFO("[%6d]Publishing GPS report Lat: %f Lon %f Precision %d SatNum %d",
00165 itsCurrMessageID, lat, lon,precision,satNum);
00166 this->publish("GPSMessageTopic", msg);
00167
00168
00169
00170 itsCurrMessageID++;
00171 }
00172 else
00173 LINFO("Waiting GPS... Lat: %f Lon %f Precision %d SatNum %d", lat, lon,precision,satNum);
00174
00175 itsData.lat = lat;
00176 itsData.lon = lon;
00177 itsData.precision = precision;
00178 itsData.satNum = satNum;
00179
00180
00181 plotGPS();
00182 }
00183 else
00184 {
00185 LERROR("Invalid Frame Size Received from GPS!");
00186 }
00187 usleep(100000);
00188 }
00189 void BeoGPS::updatePosition(double lat,double lon)
00190 {
00191
00192 double R = 6378.7 ;
00193 double theta = DEG2RAD(itsInitLon - lon);
00194 double d1 = sin(DEG2RAD(itsInitLat)) * sin(DEG2RAD(itsInitLat));
00195 double d2 = cos(DEG2RAD(itsInitLat)) * cos(DEG2RAD(itsInitLat)) * cos(theta);
00196 double y = acos(d1 + d2) * R * 1000.0;
00197
00198
00199 d1 = sin(DEG2RAD(itsInitLat)) * sin(DEG2RAD(lat));
00200 d2 = cos(DEG2RAD(itsInitLat)) * cos(DEG2RAD(lat));
00201 double x = acos(d1 + d2) * R * 1000.0;
00202
00203 if(x != 0.0 && y != 0.0)
00204 {
00205 itsPosition.x = (itsInitLat > lat) ? x : -x;
00206 itsPosition.y = (itsInitLon > lon) ? y : -y;
00207 }
00208
00209 LINFO("Publishing GPS report Lat: %f Lon: %f X: %f Y: %f",
00210 lat, lon, itsPosition.x, itsPosition.y);
00211 }
00212
00213
00214 void BeoGPS::updateMessage(const RobotSimEvents::EventMessagePtr& eMsg,
00215 const Ice::Current&)
00216 { }
00217
00218
00219 void BeoGPS::plotGPS()
00220 {
00221 if(itsDisplayTimer.getSecs() > itsDisplayUpdateRate)
00222 {
00223 itsDisplayTimer.reset();
00224
00225
00226 double mapScale = 1.0;
00227 Point2D<int> drawPos
00228 (int(itsPosition.x*mapScale + itsDispImage.getWidth()/2),
00229 int(itsPosition.y*mapScale + itsDispImage.getHeight()/2));
00230 if(itsDispImage.coordsOk(drawPos))
00231 itsDispImage.setVal(drawPos, PixRGB<byte>(0,255,0));
00232
00233
00234
00235
00236 Image<PixRGB<byte> > itsDrawitsDispImage(itsDispImage);
00237 drawCircle(itsDrawitsDispImage, drawPos, 7, PixRGB<byte>(255,255,255));
00238
00239 char buffer[128];
00240 sprintf(buffer, "X=%2.2f Y=%2.2f Lon: %1.7f Lat: %1.7f PCSN: %-3d SatNum: %-3d",
00241 itsPosition.x,itsPosition.y,
00242 itsData.lat,itsData.lon,
00243 itsData.precision,itsData.satNum);
00244 writeText(itsDispImage, Point2D<int>(0,0), buffer, PixRGB<byte>(255,255,255),
00245 PixRGB<byte>(0,0,0),SimpleFont::FIXED(8));
00246
00247 itsOfs->writeRGB(itsDispImage, "GPSData", FrameInfo("GPSData",SRC_POS));
00248 itsOfs->updateNext();
00249 }
00250 }
00251
00252
00253
00254
00255
00256