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/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
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
00180 ph.param("an", shared.Tnn,1.0);
00181 ph.param("bn", shared._Tnn,1.0);
00182
00183
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
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