diver_sim.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/ros/diver_sim.h>
00038 #include <labust/math/NumberManipulation.hpp>
00039 
00040 #include <auv_msgs/NavSts.h>
00041 #include <sensor_msgs/JointState.h>
00042 
00043 using namespace labust::simulation;
00044 
00045 DiverSim::DiverSim():
00046                 jnames(20,""),
00047                 jdefaults(60,0),
00048                 move_head(false),
00049                 runSim(false),
00050                 Ts(0.1)
00051 {
00052         this->onInit();
00053 }
00054 
00055 void DiverSim::onInit()
00056 {
00057         ros::NodeHandle nh,ph("~");
00058 
00059         //Look first in the simulation namespace
00060         nh.param("simulation/sampling_time",Ts,Ts);
00061         //Look in the private namespace for override
00062         ph.param("sampling_time", Ts, Ts);
00063         //Configure model
00064         model.setTs(Ts);
00065 
00066         //Load joint names and defaults
00067         ph.param("joint_names",jnames,jnames);
00068         ph.param("joint_defaults",jdefaults,jdefaults);
00069         ph.param("move_head", move_head, move_head);
00070 
00071         if (jdefaults.size() != 3*jnames.size())
00072         {
00073                 ROS_ERROR("Parameter joint_defaults needs to have 3x the size of parameter joint_names.");
00074                 throw std::runtime_error("Invalid size of parameter joint_defaults");
00075         }
00076 
00077         //Setup the default joint position
00078         for(int i=0; i<jnames.size(); ++i)
00079         {
00080                 jstate.name.push_back(jnames[i] + "_x");
00081                 jstate.name.push_back(jnames[i] + "_y");
00082                 jstate.name.push_back(jnames[i] + "_z");
00083         jstate.position.push_back(jdefaults[3*i]);
00084         jstate.position.push_back(jdefaults[3*i+1]);
00085         jstate.position.push_back(jdefaults[3*i+2]);
00086         }
00087 
00088         navsts = nh.advertise<auv_msgs::NavSts>("state",1);
00089         joints = nh.advertise<sensor_msgs::JointState>("joint_states",1);
00090         nusub = nh.subscribe<auv_msgs::BodyVelocityReq>("diver_nu",1,&DiverSim::onNu,this);
00091 
00092         runner = boost::thread(boost::bind(&DiverSim::start, this));
00093 }
00094 
00095 void DiverSim::start()
00096 {
00097         runSim = true;
00098         ros::Rate rate(1/Ts);
00099         while (ros::ok() && runSim)
00100         {
00101                 this->step();
00102                 rate.sleep();
00103         }
00104 }
00105 
00106 void DiverSim::step()
00107 {
00108         double hpan(0),htilt(0);
00109         auv_msgs::NavSts::Ptr nav(new auv_msgs::NavSts());
00110         {
00111                 boost::mutex::scoped_lock l(nu_mux);
00112                 labust::tools::vectorToPoint(nu, nav->body_velocity);
00113                 labust::tools::vectorToRPY(nu, nav->orientation_rate,3);
00114                 if (move_head)
00115                 {
00116                         enum {p = 3, q =4};
00117                         hpan = nu(p);
00118                         htilt = nu(q);
00119                         //Reset rates to avoid influence on body
00120                         nu(p) = 0;
00121                         nu(q) = 0;
00122                 }
00123                 //Simulate
00124                 model.step(nu);
00125                 if (move_head)
00126                 {
00127                         enum {p = 3, q =4};
00128                         //Recover speeds for future use
00129                         nu(p) = hpan;
00130                         nu(q) = htilt;
00131                 }
00132         }
00133 
00134         labust::tools::vectorToNED(model.position(), nav->position);
00135         labust::tools::vectorToRPY(model.orientation(), nav->orientation);
00136         //Clear the roll/pitch axes to allow for head control
00137         nav->orientation.roll = 0;
00138         nav->orientation.pitch = 0;
00139         nav->header.stamp = ros::Time::now();
00140         navsts.publish(nav);
00141 
00142         //Assume the interval of oscillations is proportional to speed (it's not, but anyways)
00143         this->stepJoints(nav->body_velocity.x*4, hpan, htilt);
00144         jstate.header.stamp = ros::Time::now();
00145         joints.publish(jstate);
00146 }
00147 
00148 void DiverSim::stepJoints(double w, double hpan, double htilt)
00149 {
00150         const double FOOT_LAG(M_PI/2-M_PI/12);
00151         const double THIGH_LAG(-M_PI/12);
00152         static double t=0;
00153         static double w0=0;
00154         static double T=0.4;
00156         enum {LCALF=3*12+1, RCALF=3*17+1,
00157                 LFOOT=3*11+1, RFOOT=3*18+1,
00158                 LTHIGH=3*13+1, RTHIGH=3*16+1,
00159                 LBACKZ=3*14+2, LBACKX=3*14,
00160                 HEADZ = 3*3+2, HEADY = 3*3+1};
00161         double C = w0*t;
00162         w0 = (w*Ts + w0*T)/(Ts+T);
00163         t = ((fabs(w0) > 0.01)?C/w0:0);
00164         t += Ts;
00165 
00166         jstate.position[LCALF] = jdefaults[LCALF] + M_PI/12*sin(w0*t);
00167         jstate.position[LFOOT] = jdefaults[LFOOT] - M_PI/12*sin(w0*t+FOOT_LAG);
00168         jstate.position[LTHIGH] = jdefaults[LTHIGH] + M_PI/36*sin(w0*t+THIGH_LAG);
00169         jstate.position[RCALF] = jdefaults[RCALF] - M_PI/12*sin(w0*t);
00170         jstate.position[RFOOT] = jdefaults[RFOOT] + M_PI/12*sin(w0*t+FOOT_LAG);
00171         jstate.position[RTHIGH] = jdefaults[RTHIGH] - M_PI/36*sin(w0*t+THIGH_LAG);
00172 
00173         //jstate.position[LBACKZ] = labust::math::wrapRad(jdefaults[LBACKZ] - M_PI/96*sin(w0*t));
00174         //jstate.position[LBACKX] = jdefaults[LBACKX] - M_PI/96*sin(w0*t);
00175 
00176         //Head state
00177         jstate.position[HEADZ] = labust::math::wrapRad(jdefaults[HEADZ] + hpan);
00178         jstate.position[HEADY] = labust::math::wrapRad(jdefaults[HEADY] + htilt);
00179 }
00180 
00181 int main(int argc, char* argv[])
00182 {
00183         ros::init(argc,argv,"diver_sim");
00184         ros::NodeHandle nh;
00185 
00186         labust::simulation::DiverSim diver_simulator;
00187 
00188         ros::spin();
00189         return 0;
00190 }


labust_sim
Author(s): Gyula Nagy
autogenerated on Fri Aug 28 2015 11:22:38