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 #include <labust/control/TopsideRadio.hpp>
00038 #include <labust/tools/GeoUtilities.hpp>
00039 #include <labust/tools/conversions.hpp>
00040 #include <labust/tools/MatrixLoader.hpp>
00041 #include <navcon_msgs/SetHLMode.h>
00042 #include <navcon_msgs/HLMessage.h>
00043 #include <cmath>
00044
00045 #include <boost/archive/binary_oarchive.hpp>
00046 #include <boost/archive/binary_iarchive.hpp>
00047 #include <boost/bind.hpp>
00048 #include <boost/regex.hpp>
00049
00050 #include <std_msgs/Bool.h>
00051
00052 #include <stdexcept>
00053
00054 using labust::control::TopsideRadio;
00055
00056 TopsideRadio::TopsideRadio():
00057 ph("~"),
00058 lastModemMsg(ros::Time::now()),
00059 timeout(10),
00060 port(io),
00061 isTopside(true),
00062 twoWayComms(false),
00063 lastMode(0)
00064 {this->onInit();}
00065
00066 TopsideRadio::~TopsideRadio()
00067 {
00068 io.stop();
00069 iorunner.join();
00070 if (client) client.shutdown();
00071 }
00072
00073 void TopsideRadio::onInit()
00074 {
00075 ros::NodeHandle nh,ph("~");
00076
00077 std::string portName("/dev/ttyUSB0");
00078 int baud(9600);
00079 ph.param("PortName",portName,portName);
00080 ph.param("BaudRate",baud,baud);
00081 ph.param("IsTopside",isTopside,isTopside);
00082 ph.param("TwoWay",twoWayComms,twoWayComms);
00083 ph.param("Timeout",timeout,timeout);
00084
00085 port.open(portName);
00086 port.set_option(boost::asio::serial_port::baud_rate(baud));
00087
00088 if (!port.is_open())
00089 {
00090 ROS_ERROR("Cannot open port.");
00091 throw std::runtime_error("Unable to open the port.");
00092 }
00093
00094 if (isTopside)
00095 {
00096 extPoint = nh.subscribe<auv_msgs::NavSts>("target_point", 1,
00097 &TopsideRadio::onExtPoint,this);
00098 joyIn = nh.subscribe<sensor_msgs::Joy>("joy_in",1,&TopsideRadio::onJoy,this);
00099 stateHatPub = nh.advertise<auv_msgs::NavSts>("stateHat",1);
00100 stateMeasPub = nh.advertise<auv_msgs::NavSts>("meas",1);
00101 info = nh.advertise<std_msgs::Float32MultiArray>("cart2_info",1);
00102 selectedPoint = nh.advertise<geometry_msgs::PointStamped>("selected_point", 1);
00103 selectedNavSts = nh.advertise<auv_msgs::NavSts>("selected_navsts", 1);
00104
00105
00106 server.setCallback(boost::bind(&TopsideRadio::dynrec_cb, this, _1, _2));
00107
00108 nh.param("LocalOriginLat",originLat,originLat);
00109 nh.param("LocalOriginLon",originLon,originLon);
00110 }
00111 else
00112 {
00113 joyOut = nh.advertise<sensor_msgs::Joy>("joy_out",1);
00114 launched = nh.advertise<std_msgs::Bool>("launched",1);
00115 hlMsg = nh.advertise<navcon_msgs::HLMessage>("hl_message",1);
00116 client = nh.serviceClient<navcon_msgs::SetHLMode>("SetHLMode", true);
00117 stateHat = nh.subscribe<auv_msgs::NavSts>("stateHat",1,&TopsideRadio::onStateHat,this);
00118 stateMeas = nh.subscribe<auv_msgs::NavSts>("meas",1,&TopsideRadio::onStateMeas,this);
00119 sfFrame = nh.subscribe<auv_msgs::NavSts>("sf_diagnostics",1,&TopsideRadio::onSFMeas,this);
00120 curMode = nh.subscribe<std_msgs::Int32>("current_mode",1,&TopsideRadio::onCurrentMode,this);
00121 cartInfo = nh.subscribe<std_msgs::Float32MultiArray>("cart2_info",1,&TopsideRadio::onCartInfo,this);
00122 }
00123
00124 populateDataFromConfig();
00125 cdata.origin_lat = 0;
00126 cdata.origin_lon = 0;
00127 cdata.mode = 0;
00128 cdata.sf_state[x]= cdata.sf_state[y]= cdata.sf_state[psi]= 0;
00129 data.mode = 0;
00130 data.surgeForce = data.torqueForce = 0;
00131
00132 this->start_receive();
00133 iorunner = boost::thread(boost::bind(&boost::asio::io_service::run,&io));
00134 }
00135
00136 void TopsideRadio::onJoy(const sensor_msgs::Joy::ConstPtr& joy)
00137 {
00138 boost::mutex::scoped_lock l(dataMux);
00139 data.surgeForce = joy->axes[1]*100;
00140 data.torqueForce = joy->axes[2]*100;
00141 }
00142
00143 void TopsideRadio::onExtPoint(const auv_msgs::NavSts::ConstPtr& extPoint)
00144 {
00145 if (!config.ManualPoint)
00146 {
00147 boost::mutex::scoped_lock l(dataMux);
00148 if (extPoint->header.frame_id == "worldLatLon")
00149 {
00150 data.lat = extPoint->global_position.latitude*10000000;
00151 data.lon = extPoint->global_position.longitude*10000000;
00152 }
00153 else if (extPoint->header.frame_id == "local")
00154 {
00155 local2LatLon(extPoint->position.north, extPoint->position.east);
00156 }
00157 else
00158 {
00159 ROS_ERROR("The specified point for the radio modem has to be in worldLatLon frame!.");
00160 }
00161 }
00162 }
00163
00164 void TopsideRadio::onCurrentMode(const std_msgs::Int32::ConstPtr& mode)
00165 {
00166 boost::mutex::scoped_lock l(cdataMux);
00167 cdata.mode = mode->data;
00168 lastMode = mode->data;
00169 }
00170
00171 void TopsideRadio::onStateHat(const auv_msgs::NavSts::ConstPtr& estimate)
00172 {
00173 boost::mutex::scoped_lock l(cdataMux);
00174 cdata.state_hat[u] = estimate->body_velocity.x*100;
00175
00176 cdata.state_hat[x] = estimate->position.north*100;
00177 cdata.state_hat[y] = estimate->position.east*100;
00178 cdata.state_hat[psi] = estimate->orientation.yaw*100;
00179
00180 try
00181 {
00182 tf::StampedTransform transformLocal;
00183 listener.lookupTransform("/worldLatLon", "local", ros::Time(0), transformLocal);
00184 cdata.origin_lat = transformLocal.getOrigin().y()*10000000;
00185 cdata.origin_lon = transformLocal.getOrigin().x()*10000000;
00186 }
00187 catch(tf::TransformException& ex)
00188 {
00189 ROS_ERROR("%s",ex.what());
00190 }
00191 }
00192
00193 void TopsideRadio::onStateMeas(const auv_msgs::NavSts::ConstPtr& meas)
00194 {
00195 boost::mutex::scoped_lock l(cdataMux);
00196
00197
00198 cdata.state_meas[x] = meas->position.north*100;
00199 cdata.state_meas[y] = meas->position.east*100;
00200 cdata.state_meas[psi] = meas->orientation.yaw*100;
00201 }
00202
00203 void TopsideRadio::onSFMeas(const auv_msgs::NavSts::ConstPtr& meas)
00204 {
00205 boost::mutex::scoped_lock l(cdataMux);
00206
00207
00208 cdata.sf_state[x] = meas->position.north*100;
00209 cdata.sf_state[y] = meas->position.east*100;
00210 cdata.sf_state[psi] = meas->orientation.yaw*100;
00211 }
00212
00213 void TopsideRadio::onCartInfo(const std_msgs::Float32MultiArray::ConstPtr& info)
00214 {
00215 boost::mutex::scoped_lock l(cdataMux);
00216 enum {port_rpm_desired=0,
00217 stbd_rpm_desired,
00218 port_rpm_meas,
00219 stbd_rpm_meas,
00220 port_curr_desired,
00221 stbd_curr_desired,
00222 current,
00223 temp,
00224 voltage
00225 };
00226
00227 cdata.portRPM = info->data[port_rpm_meas];
00228 cdata.stbdRPM = info->data[stbd_rpm_meas];
00229 cdata.voltage = info->data[voltage]/50*256;
00230 cdata.temp = info->data[temp]/100*256;
00231 }
00232
00233 void TopsideRadio::local2LatLon(double x, double y)
00234 {
00235 std::pair<double, double> location = labust::tools::meter2deg(x,
00236 y,
00237 originLat);
00238 data.lat = (originLat + location.first)*10000000;
00239 data.lon = (originLon + location.second)*10000000;
00240 }
00241
00242 void TopsideRadio::populateDataFromConfig()
00243 {
00244 boost::mutex::scoped_lock l(dataMux);
00245 data.mode_update = 1;
00246 data.mode = config.OpMode;
00247 data.launch = config.Launch;
00248 if (config.ManualPoint)
00249 {
00250 if (config.UseLocal)
00251 {
00252 local2LatLon(config.PointN, config.PointE);
00253 }
00254 else
00255 {
00256 data.lat = config.PointLat*10000000;
00257 data.lon = config.PointLon*10000000;
00258 }
00259 }
00260 data.radius = config.Radius;
00261 data.surge = config.Surge*100;
00262 data.yaw = std::floor(config.Yaw/M_PI*128+0.5);
00263 }
00264
00265 void TopsideRadio::dynrec_cb(cart2::RadioModemConfig& config, uint32_t level)
00266 {
00267 if ((config.OpMode != this->config.OpMode) &&
00268 (config.OpMode == 0))
00269 {
00270
00271 config.Launch = 0;
00272 server.updateConfig(config);
00273 }
00274 this->config = config;
00275 this->populateDataFromConfig();
00276
00277 if (config.ManualPoint && config.UseLocal)
00278 {
00279 geometry_msgs::PointStamped point;
00280 point.header.frame_id = "local";
00281 point.header.stamp = ros::Time::now();
00282 point.point.x = this->config.PointN;
00283 point.point.y = this->config.PointE;
00284 selectedPoint.publish(point);
00285 }
00286 }
00287
00288 void TopsideRadio::start_receive()
00289 {
00290 boost::asio::async_read(port, sbuffer.prepare(sync_length),
00291 boost::bind(&TopsideRadio::onSync,this,_1,_2));
00292 }
00293
00294 void TopsideRadio::onSync(const boost::system::error_code& error, const size_t& transferred)
00295 {
00296 if (!error)
00297 {
00298 sbuffer.commit(transferred);
00299
00300 if (transferred == 1)
00301 {
00302 ringBuffer.push_back(sbuffer.sbumpc());
00303 if (ringBuffer.size() > sync_length)
00304 {
00305 ringBuffer.erase(ringBuffer.begin());
00306 }
00307 }
00308 else
00309 {
00310 std::istream is(&sbuffer);
00311 ringBuffer.clear();
00312 is >> ringBuffer;
00313 }
00314
00315 if ((ringBuffer.size() >= sync_length) && (ringBuffer.substr(0,sync_length) == "@T"))
00316 {
00317 ROS_INFO("Synced on @ONTOP");
00318 assert(!isTopside && "Cannot receive topside messages if on topside.");
00319 boost::asio::async_read(port,sbuffer.prepare(topside_package_length),boost::bind(&TopsideRadio::onIncomingData,this,_1,_2));
00320 }
00321 else if ((ringBuffer.size() >= sync_length) && (ringBuffer.substr(0,sync_length) == "@C"))
00322 {
00323 ROS_INFO("Synced on @CART2");
00324 assert(isTopside && "Cannot receive CART messages if on cart.");
00325 boost::asio::async_read(port,sbuffer.prepare(cart_package_length),boost::bind(&TopsideRadio::onIncomingData,this,_1,_2));
00326 }
00327 else
00328 {
00329 ROS_INFO("No sync: %s",ringBuffer.c_str());
00330 boost::asio::async_read(port, sbuffer.prepare(1),
00331 boost::bind(&TopsideRadio::onSync,this,_1,_2));
00332 }
00333 }
00334 }
00335
00336 void TopsideRadio::onIncomingData(const boost::system::error_code& error, const size_t& transferred)
00337 {
00338 sbuffer.commit(transferred);
00339
00340 if (!error)
00341 {
00342 boost::archive::binary_iarchive dataSer(sbuffer, boost::archive::no_header);
00343 ROS_INFO("Received:%d", transferred);
00344
00345 ROS_INFO("Received %d bytes.",transferred);
00346
00347 if (!isTopside)
00348 {
00349 boost::mutex::scoped_lock l(dataMux);
00350 uint16_t chksum(0);
00351 try
00352 {
00353 dataSer >> data >> chksum;
00354 }
00355 catch (std::exception& e)
00356 {
00357 ROS_ERROR("Exception while deserializing: %s",e.what());
00358 }
00359
00360 uint16_t chksum_calc = calculateCRC16(data);
00361 if (chksum_calc != chksum)
00362 {
00363 ROS_ERROR("Wrong checksum! Got: %d, expected: %d",chksum, chksum_calc);
00364 start_receive();
00365 return;
00366 }
00367
00368 sensor_msgs::Joy joy;
00369 joy.axes.assign(6,0);
00370
00371 if (fabs(data.surgeForce) > 100)
00372 {
00373 ROS_ERROR("Remote joystick force is above 1.");
00374 data.surgeForce = 0;
00375 }
00376
00377 if (fabs(data.torqueForce) > 100)
00378 {
00379 ROS_ERROR("Remote joystick force is above 1.");
00380 data.torqueForce = 0;
00381 }
00382
00383 joy.axes[1] = data.surgeForce/100.;
00384 joy.axes[2] = data.torqueForce/100.;
00385
00386 std_msgs::Bool launcher;
00387 launcher.data = data.launch;
00388
00389
00390
00391 if (data.mode > 8)
00392 {
00393 data.mode = 0;
00394 ROS_ERROR("Wrong mode.");
00395 return;
00396 }
00397 navcon_msgs::HLMessagePtr msg(new navcon_msgs::HLMessage());
00398 bool update = data.mode_update;
00399 msg->mode = data.mode;
00400 msg->radius = data.radius;
00401 msg->ref_point.header.stamp=ros::Time::now();
00402 msg->ref_point.header.frame_id="worldLatLon";
00403 msg->ref_point.point.x = data.lat/10000000.;
00404 msg->ref_point.point.y = data.lon/10000000.;
00405 msg->surge = data.surge/100.;
00406 l.unlock();
00407
00408 joyOut.publish(joy);
00409 if (update)
00410 {
00411 hlMsg.publish(msg);
00412 launched.publish(launcher);
00413 }
00414
00415 boost::mutex::scoped_lock l2(clientMux);
00416 lastModemMsg = ros::Time::now();
00417 if (!client)
00418 {
00419 ROS_ERROR("HLManager client not connected. Trying reset.");
00420 client = nh.serviceClient<navcon_msgs::SetHLMode>("SetHLMode", true);
00421 }
00422 else
00423 {
00424 boost::mutex::scoped_lock l(dataMux);
00425 navcon_msgs::SetHLMode mode;
00426 if (update)
00427 {
00428 lastMode = mode.request.mode = data.mode;
00429 }
00430 else
00431 {
00432 mode.request.mode = lastMode;
00433 }
00434 mode.request.ref_point.header.stamp=ros::Time::now();
00435 mode.request.ref_point.header.frame_id="worldLatLon";
00436 mode.request.ref_point.point.x = data.lat/10000000.;
00437 mode.request.ref_point.point.y = data.lon/10000000.;
00438 mode.request.radius = data.radius;
00439 mode.request.surge = data.surge/100.;
00440 mode.request.yaw = M_PI*data.yaw/128.;
00441 l.unlock();
00442 if (!(data.launch && (data.mode == 0))) client.call(mode);
00443 }
00444 l2.unlock();
00445
00446 if (twoWayComms)
00447 {
00448 boost::asio::streambuf output;
00449 std::ostream out(&output);
00450
00451 out<<"@C";
00452 boost::archive::binary_oarchive dataSer(output, boost::archive::no_header);
00453 boost::mutex::scoped_lock l(cdataMux);
00454 uint16_t chksum_calc = calculateCRC16(cdata);
00455 try
00456 {
00457 dataSer << cdata << chksum_calc;
00458 }
00459 catch (std::exception& e)
00460 {
00461 ROS_ERROR("Exception while serializing: %s",e.what());
00462 }
00463 l.unlock();
00464
00465 int n = boost::asio::write(port, output.data());
00466 ROS_INFO("Transferred:%d",n);
00467 }
00468 }
00469 else
00470 {
00471 boost::mutex::scoped_lock l(cdataMux);
00472 uint16_t chksum(0);
00473 try
00474 {
00475 dataSer >> cdata >> chksum;
00476 }
00477 catch (std::exception& e)
00478 {
00479 ROS_ERROR("Exception while serializing: %s",e.what());
00480 }
00481
00482 uint16_t chksum_calc = calculateCRC16(cdata);
00483 if (chksum_calc != chksum)
00484 {
00485 ROS_ERROR("Wrong checksum! Got: %d, expected: %d",chksum, chksum_calc);
00486 start_receive();
00487 return;
00488 }
00489
00490 auv_msgs::NavStsPtr state(new auv_msgs::NavSts());
00491 auv_msgs::NavStsPtr meas(new auv_msgs::NavSts());
00492 state->origin.latitude = cdata.origin_lat/10000000.;
00493 state->origin.longitude = cdata.origin_lon/10000000.;
00494 state->body_velocity.x = cdata.state_hat[u]/100.;
00495
00496 state->position.north = cdata.state_hat[x]/100.;
00497 state->position.east = cdata.state_hat[y]/100.;
00498 state->orientation.yaw = cdata.state_hat[psi]/100.;
00499 meas->origin.latitude = cdata.origin_lat/10000000.;
00500 meas->origin.longitude = cdata.origin_lon/10000000.;
00501
00502
00503 meas->position.north = cdata.state_meas[x]/100.;
00504 meas->position.east = cdata.state_meas[y]/100.;
00505 meas->orientation.yaw = cdata.state_meas[psi]/100.;
00506
00507 std::pair<double, double> location = labust::tools::meter2deg(
00508 state->position.north,
00509 state->position.east,
00510 state->origin.latitude);
00511 state->global_position.latitude = state->origin.latitude + location.first;
00512 state->global_position.longitude = state->origin.longitude + location.second;
00513
00514 location = labust::tools::meter2deg(
00515 meas->position.north,
00516 meas->position.east,
00517 meas->origin.latitude);
00518 meas->global_position.latitude = state->origin.latitude + location.first;
00519 meas->global_position.longitude = state->origin.longitude + location.second;
00520
00521 std_msgs::Float32MultiArray cinfo;
00522 cinfo.data.resize(4);
00523 cinfo.data[0] = cdata.voltage/256.*50;
00524 cinfo.data[1] = cdata.temp/256.*100;
00525 cinfo.data[2] = cdata.portRPM;
00526 cinfo.data[3] = cdata.stbdRPM;
00527 info.publish(cinfo);
00528
00529 ROS_INFO("Current CART2 mode:%d",cdata.mode);
00530
00531 tf::Transform transform;
00532 transform.setOrigin(tf::Vector3(cdata.origin_lon/10000000., cdata.origin_lat/10000000., 0));
00533 originLon = cdata.origin_lon/10000000.;
00534 originLat = cdata.origin_lat/10000000.;
00535 l.unlock();
00536
00537 transform.setRotation(tf::createQuaternionFromRPY(0,0,0));
00538 broadcaster.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "worldLatLon", "world"));
00539 transform.setOrigin(tf::Vector3(0, 0, 0));
00540 Eigen::Quaternion<float> q;
00541 labust::tools::quaternionFromEulerZYX(M_PI,0,M_PI/2,q);
00542 transform.setRotation(tf::Quaternion(q.x(),q.y(),q.z(),q.w()));
00543 broadcaster.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", "local"));
00544 transform.setOrigin(tf::Vector3(state->position.north, state->position.east, 0));
00545 labust::tools::quaternionFromEulerZYX(0,0,state->orientation.yaw,q);
00546 transform.setRotation(tf::Quaternion(q.x(),q.y(),q.z(),q.w()));
00547 broadcaster.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "local", "base_link"));
00548 transform.setOrigin(tf::Vector3(meas->position.north, meas->position.east, 0));
00549 labust::tools::quaternionFromEulerZYX(0,0,meas->orientation.yaw,q);
00550 transform.setRotation(tf::Quaternion(q.x(),q.y(),q.z(),q.w()));
00551 broadcaster.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "local", "base_link_meas"));
00552 transform.setOrigin(tf::Vector3(cdata.sf_state[x]/100.,cdata.sf_state[y]/100., 0));
00553 labust::tools::quaternionFromEulerZYX(0,0,cdata.sf_state[psi]/100.,q);
00554 transform.setRotation(tf::Quaternion(q.x(),q.y(),q.z(),q.w()));
00555 broadcaster.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "local", "sf_frame"));
00556
00557 stateHatPub.publish(state);
00558 stateMeasPub.publish(meas);
00559 }
00560 }
00561 else
00562 {
00563 ROS_ERROR("Communication failed.");
00564 }
00565
00566 start_receive();
00567 }
00568
00569 void TopsideRadio::onTimeout()
00570 {
00571 if (!client)
00572 {
00573 ROS_ERROR("HLManager client not connected. Trying reset.");
00574 client = nh.serviceClient<navcon_msgs::SetHLMode>("SetHLMode", true);
00575 }
00576 else
00577 {
00578 navcon_msgs::SetHLMode mode;
00579 mode.request.mode = 0;
00580 client.call(mode);
00581 }
00582
00583 ROS_ERROR("Lost connection with topside!");
00584
00585 io.stop();
00586 iorunner.join();
00587 port.close();
00588
00589 io.reset();
00590 lastModemMsg = ros::Time::now();
00591 ros::Rate rate(1);
00592 for(int i=0;i<3;++i) rate.sleep();
00593
00594 std::string portName;
00595 int baud;
00596 ph.param("PortName",portName,portName);
00597 ph.param("BaudRate",baud,baud);
00598
00599 port.open(portName);
00600 port.set_option(boost::asio::serial_port::baud_rate(baud));
00601
00602 if (!port.is_open())
00603 {
00604 ROS_ERROR("Cannot open port.");
00605 throw std::runtime_error("Unable to open the port.");
00606 }
00607
00608 this->start_receive();
00609 iorunner = boost::thread(boost::bind(&boost::asio::io_service::run,&io));
00610 }
00611
00612 void TopsideRadio::start()
00613 {
00614 if (!isTopside)
00615 {
00616 ros::Rate rate(20);
00617
00618 while (ros::ok())
00619 {
00620 rate.sleep();
00621 ros::spinOnce();
00622 boost::mutex::scoped_lock l(clientMux);
00623 if ((ros::Time::now()-lastModemMsg).toSec() > timeout )
00624 {
00625 this->onTimeout();
00626 }
00627 }
00628 }
00629 else
00630 {
00631 double transmitRate(10);
00632 ros::NodeHandle ph("~");
00633 ph.param("TransmitRate",transmitRate,transmitRate);
00634 ros::Rate rate(transmitRate);
00635 while (nh.ok())
00636 {
00637 boost::asio::streambuf output;
00638 std::ostream out(&output);
00639 std::ostringstream chk;
00640
00641 out<<"@T";
00642 boost::archive::binary_oarchive dataSer(output, boost::archive::no_header);
00643 boost::mutex::scoped_lock l(dataMux);
00644 uint16_t chksum_calc = calculateCRC16(data);
00645 try
00646 {
00647 dataSer << data << chksum_calc;
00648 }
00649 catch (std::exception& e)
00650 {
00651 ROS_ERROR("Exception while serializing: %s",e.what());
00652 }
00653 data.mode_update = 0;
00654 l.unlock();
00655
00656
00657 int n = boost::asio::write(port, output.data());
00658 ROS_INFO("Transferred %d bytes.",n);
00659
00660 if (config.OpMode == 7)
00661 {
00662 auv_msgs::NavSts selected;
00663 boost::mutex::scoped_lock l(cdataMux);
00664 std::pair<double, double> location = labust::tools::meter2deg(cdata.sf_state[x]/100.,
00665 cdata.sf_state[y]/100.,
00666 originLat);
00667 selected.global_position.latitude = originLat + location.first;
00668 selected.global_position.longitude = originLon + location.second;
00669 selected.position.north = cdata.sf_state[x]/100.;
00670 selected.position.east = cdata.sf_state[y]/100.;
00671 selected.orientation.yaw = cdata.sf_state[psi]/100.;
00672 selectedNavSts.publish(selected);
00673
00674 geometry_msgs::PointStamped point;
00675 point.header.frame_id = "local";
00676 point.header.stamp = ros::Time::now();
00677 point.point.x = cdata.sf_state[x]/100.;
00678 point.point.y = cdata.sf_state[y]/100.;
00679 selectedPoint.publish(point);
00680
00681 }
00682
00683 if ((config.OpMode != 7) && config.ManualPoint)
00684 {
00685 auv_msgs::NavSts selected;
00686 if (config.UseLocal)
00687 {
00688 std::pair<double, double> location = labust::tools::meter2deg(config.PointN,
00689 config.PointE,
00690 originLat);
00691 selected.global_position.latitude = originLat + location.first;
00692 selected.global_position.longitude = originLon + location.second;
00693 selected.position.north = config.PointN;
00694 selected.position.east = config.PointE;
00695 }
00696 else
00697 {
00698 selected.global_position.latitude = config.PointLat;
00699 selected.global_position.longitude = config.PointLon;
00700 std::pair<double, double> location = labust::tools::deg2meter(config.PointLat - originLat,
00701 config.PointLon - originLon,
00702 originLat);
00703 selected.position.north = location.first;
00704 selected.position.east = location.second;
00705 }
00706 selectedNavSts.publish(selected);
00707 }
00708
00709
00710 rate.sleep();
00711 ros::spinOnce();
00712 }
00713 }
00714 }
00715