Go to the documentation of this file.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 #include <ublox_gps/gps.h>
00031
00032 namespace ublox_gps {
00033
00034 using namespace ublox_msgs;
00035
00036 boost::posix_time::time_duration Gps::default_timeout_(boost::posix_time::seconds(1.0));
00037 Gps::Gps()
00038 : configured_(false)
00039 , baudrate_(57600)
00040 {
00041 }
00042
00043 Gps::~Gps()
00044 {
00045 close();
00046 }
00047
00048 bool Gps::setBaudrate(unsigned int baudrate)
00049 {
00050 baudrate_ = baudrate;
00051 if (!worker_) return true;
00052
00053 CfgPRT port;
00054 port.baudRate = baudrate_;
00055 port.mode = CfgPRT::MODE_RESERVED1 | CfgPRT::MODE_CHAR_LEN_8BIT | CfgPRT::MODE_PARITY_NO | CfgPRT::MODE_STOP_BITS_1;
00056 port.inProtoMask = CfgPRT::PROTO_UBX | CfgPRT::PROTO_NMEA | CfgPRT::PROTO_RTCM;
00057 port.outProtoMask = CfgPRT::PROTO_UBX;
00058 port.portID = CfgPRT::PORT_ID_UART1;
00059
00060 return configure(port);
00061 }
00062
00063 void Gps::initialize(const boost::shared_ptr<Worker> &worker)
00064 {
00065 if (worker_) return;
00066 worker_ = worker;
00067 worker_->setCallback(boost::bind(&Gps::readCallback, this, _1, _2));
00068 configured_ = worker;
00069 }
00070
00071 template void Gps::initialize(boost::asio::ip::tcp::socket& stream, boost::asio::io_service& io_service);
00072
00073
00074 template <>
00075 void Gps::initialize(boost::asio::serial_port& serial_port, boost::asio::io_service& io_service)
00076 {
00077 if (worker_) return;
00078 initialize(boost::shared_ptr<Worker>(new AsyncWorker<boost::asio::serial_port>(serial_port, io_service)));
00079
00080 configured_ = false;
00081
00082 boost::asio::serial_port_base::baud_rate current_baudrate;
00083
00084 serial_port.set_option(boost::asio::serial_port_base::baud_rate(4800));
00085 boost::this_thread::sleep(boost::posix_time::milliseconds(500));
00086 if (debug) { serial_port.get_option(current_baudrate); std::cout << "Set baudrate " << current_baudrate.value() << std::endl; }
00087 configured_ = setBaudrate(baudrate_);
00088 if (configured_) return;
00089
00090 serial_port.set_option(boost::asio::serial_port_base::baud_rate(9600));
00091 boost::this_thread::sleep(boost::posix_time::milliseconds(500));
00092 if (debug) { serial_port.get_option(current_baudrate); std::cout << "Set baudrate " << current_baudrate.value() << std::endl; }
00093 configured_ = setBaudrate(baudrate_);
00094 if (configured_) return;
00095
00096 serial_port.set_option(boost::asio::serial_port_base::baud_rate(19200));
00097 boost::this_thread::sleep(boost::posix_time::milliseconds(500));
00098 if (debug) { serial_port.get_option(current_baudrate); std::cout << "Set baudrate " << current_baudrate.value() << std::endl; }
00099 configured_ = setBaudrate(baudrate_);
00100 if (configured_) return;
00101
00102 serial_port.set_option(boost::asio::serial_port_base::baud_rate(38400));
00103 boost::this_thread::sleep(boost::posix_time::milliseconds(500));
00104 if (debug) { serial_port.get_option(current_baudrate); std::cout << "Set baudrate " << current_baudrate.value() << std::endl; }
00105 configured_ = setBaudrate(baudrate_);
00106 if (configured_) return;
00107
00108 serial_port.set_option(boost::asio::serial_port_base::baud_rate(baudrate_));
00109 boost::this_thread::sleep(boost::posix_time::milliseconds(500));
00110 if (debug) { serial_port.get_option(current_baudrate); std::cout << "Set baudrate " << current_baudrate.value() << std::endl; }
00111 configured_ = setBaudrate(baudrate_);
00112 if (configured_) return;
00113 }
00114
00115 void Gps::close()
00116 {
00117 worker_.reset();
00118 configured_ = false;
00119 }
00120
00121 bool Gps::setRate(uint8_t class_id, uint8_t message_id, unsigned int rate)
00122 {
00123 CfgMSG msg;
00124 msg.msgClass = class_id;
00125 msg.msgID = message_id;
00126 msg.rate = rate;
00127 return configure(msg);
00128 }
00129
00130 bool Gps::enableSBAS(bool onoff) {
00131 CfgSBAS msg;
00132 msg.mode = (onoff ? CfgSBAS::MODE_ENABLED : 0);
00133 msg.usage = 255;
00134 msg.maxSBAS = 3;
00135 return configure(msg);
00136 }
00137
00138 bool Gps::poll(uint8_t class_id, uint8_t message_id, const std::vector<uint8_t>& payload) {
00139 if (!worker_) return false;
00140
00141 std::vector<unsigned char> out(1024);
00142 ublox::Writer writer(out.data(), out.size());
00143 if (!writer.write(payload.data(), payload.size(), class_id, message_id)) return false;
00144 worker_->send(out.data(), writer.end() - out.data());
00145
00146 return true;
00147 }
00148
00149 bool Gps::configure()
00150 {
00151 configured_ = false;
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 CfgRATE rate;
00168 rate.measRate = 250;
00169 rate.navRate = 1;
00170 rate.timeRef = CfgRATE::TIME_REF_GPS;
00171 if (!configure(rate)) return false;
00172
00173 configured_ = true;
00174 return true;
00175 }
00176
00177 void Gps::waitForAcknowledge(const boost::posix_time::time_duration& timeout) {
00178 boost::posix_time::ptime wait_until(boost::posix_time::second_clock::local_time() + timeout);
00179
00180 while(acknowledge_ == WAIT && boost::posix_time::second_clock::local_time() < wait_until) {
00181 worker_->wait(timeout);
00182 }
00183 }
00184
00185 void Gps::readCallback(unsigned char *data, std::size_t& size) {
00186 ublox::Reader reader(data, size);
00187
00188 while(reader.search() != reader.end() && reader.found()) {
00189 if (debug >= 3) {
00190 std::cout << "received ublox " << reader.length() + 8 << " bytes" << std::endl;
00191 for(ublox::Reader::iterator it = reader.pos(); it != reader.pos() + reader.length() + 8; ++it) std::cout << std::hex << static_cast<unsigned int>(*it) << " ";
00192 std::cout << std::dec << std::endl;
00193 }
00194
00195 callback_mutex_.lock();
00196 Callbacks::key_type key = std::make_pair(reader.classId(), reader.messageId());
00197 for(Callbacks::iterator callback = callbacks_.lower_bound(key); callback != callbacks_.upper_bound(key); ++callback) callback->second->handle(reader);
00198 callback_mutex_.unlock();
00199
00200 if (reader.classId() == 0x05) {
00201 acknowledge_ = (reader.messageId() == 0x00) ? NACK : ACK;
00202 if (debug) std::cout << "received " << (acknowledge_ == ACK ? "ACK" : "NACK") << std::endl;
00203 }
00204 }
00205
00206
00207 std::copy(reader.pos(), reader.end(), data);
00208 size -= reader.pos() - data;
00209 }
00210
00211 bool CallbackHandler::wait(const boost::posix_time::time_duration &timeout) {
00212 boost::mutex::scoped_lock lock(mutex_);
00213 return condition_.timed_wait(lock, timeout);
00214 }
00215
00216 }