vr_node.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2010, LABUST, UNIZG-FER
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the LABUST nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *
00034 *  Author: Dula Nad
00035 *  Created: 01.02.2013.
00036 *********************************************************************/
00037 #include <labust/vehicles/VR3Details.hpp>
00038 #include <labust/vehicles/Allocation.hpp>
00039 #include <labust/math/NumberManipulation.hpp>
00040 #include <labust/tools/conversions.hpp>
00041 #include <labust/tools/MatrixLoader.hpp>
00042 #include <boost/asio.hpp>
00043 
00044 #include <ros/ros.h>
00045 #include <auv_msgs/BodyForceReq.h>
00046 #include <sensor_msgs/Imu.h>
00047 #include <sensor_msgs/FluidPressure.h>
00048 #include <tf/transform_broadcaster.h>
00049 
00050 #include <string>
00051 
00052 struct SharedData
00053 {
00054         enum {revLimit = 220, lightLimit=200};
00055 
00056         SharedData():port(io){};
00057 
00058         void portOpen(const std::string& portName, int baud)
00059         {
00060                 port.open(portName);
00061 
00062                 if (port.is_open())
00063                 {
00064                         using namespace boost::asio;
00065                         port.set_option(serial_port::baud_rate(baud));
00066                         port.set_option(serial_port::flow_control(serial_port::flow_control::none));
00067                         port.set_option(serial_port::parity(serial_port::parity::none));
00068                         port.set_option(serial_port::stop_bits(serial_port::stop_bits::one));
00069                         port.set_option(serial_port::character_size(8));
00070                         ROS_INFO("Port %s is open.", portName.c_str());
00071                 }
00072         }
00073 
00074         ros::Publisher tauAch, imu, depth;
00075         auv_msgs::BodyForceReq tau;
00076         tf::TransformBroadcaster broadcast;
00077         tf::Transform imuPos;
00081         double Tnn,_Tnn;
00082 
00083         boost::asio::io_service io;
00084         boost::asio::serial_port port;
00085 
00086         labust::vehicles::VRSerialComms comms;
00087         labust::vehicles::VRComms::ThrustVec thrusters;
00088 };
00089 
00090 inline double getRevs(double thrust, double Tnn = 1, double _Tnn = 1)
00091 {
00092         return (thrust >= 0) ? std::sqrt(thrust/Tnn) : -std::sqrt(-thrust/_Tnn);
00093 }
00094 
00095 void onTau(SharedData& shared, const auv_msgs::BodyForceReq::ConstPtr tau)
00096 {
00097         double port, stbd;
00098         using namespace labust::vehicles;
00099         using namespace labust::math;
00100         port = getRevs(
00101                         (tau->wrench.force.x + tau->wrench.torque.z)/2,
00102                         shared.Tnn,
00103                         shared._Tnn);
00104         stbd = getRevs(
00105                         (tau->wrench.force.x - tau->wrench.torque.z)/2,
00106                         shared.Tnn,
00107                         shared._Tnn);
00108         shared.thrusters[VRComms::vert] = -coerce(AffineThruster::getRevs(
00109                         tau->wrench.force.z,
00110                         shared.Tnn,
00111                         shared._Tnn), -SharedData::revLimit, SharedData::revLimit);
00112 
00113         ROS_INFO("Full time estimate:%f",(ros::Time::now() - tau->header.stamp).toSec());
00114 
00115         double scale(1);
00116         if (port/SharedData::revLimit > scale) scale = port/SharedData::revLimit;
00117         if (stbd/SharedData::revLimit > scale) scale = stbd/SharedData::revLimit;
00118 
00119         if (scale > 1)
00120         {
00121                 port /= scale;
00122                 stbd /= scale;
00123 
00124                 shared.tau.disable_axis.x = 1;
00125                 shared.tau.disable_axis.z = 1;
00126         }
00127 
00128         double portMux(port>0?shared.Tnn:shared._Tnn);
00129         double stbdMux(stbd>0?shared.Tnn:shared._Tnn);
00130         shared.tau.wrench.force.x = portMux*fabs(port)*port+stbdMux*fabs(stbd)*stbd;
00131         shared.tau.wrench.torque.z = portMux*fabs(port)*port-stbdMux*fabs(stbd)*stbd;
00132 
00133         //Publish achieved tau
00134         shared.tauAch.publish(shared.tau);
00135 
00136         shared.thrusters[VRComms::port] = coerce(int(std::ceil(port)),
00137                         -SharedData::revLimit, SharedData::revLimit);
00138         shared.thrusters[VRComms::stbd] = coerce(int(std::ceil(stbd)),
00139                         -SharedData::revLimit, SharedData::revLimit);
00140         shared.thrusters[VRComms::light] = 0;
00141 
00142         std::cout<<"Test propulsion:"<<shared.thrusters[VRComms::port]<<","<<shared.thrusters[VRComms::stbd]<<","<<shared.thrusters[VRComms::vert]<<std::endl;
00143 
00144         shared.comms.encode(shared.thrusters);
00145         boost::asio::write(shared.port, boost::asio::buffer(shared.comms.outputBuffer));
00146         boost::asio::read(shared.port, boost::asio::buffer(shared.comms.inputBuffer));
00147         labust::vehicles::stateMapPtr states(new labust::vehicles::stateMap());
00148         shared.comms.decode(states);
00149 
00150         sensor_msgs::FluidPressure pressure;
00151         pressure.header.frame_id = "local";
00152         pressure.fluid_pressure = ((*states)[labust::vehicles::state::depthPressure]);
00153         shared.depth.publish(pressure);
00154 
00155         sensor_msgs::Imu imu;
00156         Eigen::Quaternion<float> quat;
00157         labust::tools::quaternionFromEulerZYX(0.0, 0.0,
00158                         ((*states)[labust::vehicles::state::yaw]), quat);
00159         imu.orientation.x = quat.x();
00160         imu.orientation.y = quat.y();
00161         imu.orientation.z = quat.z();
00162         imu.orientation.w = quat.w();
00163         imu.header.stamp = ros::Time::now();
00164         shared.broadcast.sendTransform(tf::StampedTransform(shared.imuPos, ros::Time::now(), "base_link", "imu_frame"));
00165         shared.imu.publish(imu);
00166 }
00167 
00168 int main(int argc, char* argv[])
00169 {
00170         ros::init(argc,argv,"vr_node");
00171         ros::NodeHandle nh,ph("~");
00172 
00173         SharedData shared;
00174         ros::Subscriber tauIn = nh.subscribe<auv_msgs::BodyForceReq>("tauIn",1,boost::bind(&onTau,boost::ref(shared),_1));
00175         shared.tauAch = nh.advertise<auv_msgs::BodyForceReq>("tauAch",1);
00176         shared.imu = nh.advertise<sensor_msgs::Imu>("vr_imu",1);
00177         shared.depth = nh.advertise<sensor_msgs::FluidPressure>("vr_depth",1);
00178 
00179         //Get thruster configuration
00180         ph.param("an", shared.Tnn,1.0);
00181         ph.param("bn", shared._Tnn,1.0);
00182 
00183         //Get port name from configuration and open.
00184         std::string portName("/dev/ttyUSB0");
00185         int baud(9600);
00186         ph.param("PortName", portName,portName);
00187         ph.param("BaudRate", baud, baud);
00188         shared.portOpen(portName, baud);
00189 
00190         //Configure Imu and GPS position relative to vehicle center of mass
00191         Eigen::Vector3d origin(Eigen::Vector3d::Zero()),
00192                         orientation(Eigen::Vector3d::Zero());
00193 
00194         labust::tools::getMatrixParam(nh, "imu_origin", origin);
00195         labust::tools::getMatrixParam(nh, "imu_orientation", orientation);
00196         shared.imuPos.setOrigin(tf::Vector3(origin(0),origin(1),origin(2)));
00197         shared.imuPos.setRotation(tf::createQuaternionFromRPY(orientation(0),
00198                         orientation(1),orientation(2)));
00199 
00200         ros::spin();
00201         return 0;
00202 }
00203 
00204 
00205 
00206 


cart2
Author(s): Gyula Nagy
autogenerated on Fri Feb 7 2014 11:37:19