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/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
00060 nh.param("simulation/sampling_time",Ts,Ts);
00061
00062 ph.param("sampling_time", Ts, Ts);
00063
00064 model.setTs(Ts);
00065
00066
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
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
00120 nu(p) = 0;
00121 nu(q) = 0;
00122 }
00123
00124 model.step(nu);
00125 if (move_head)
00126 {
00127 enum {p = 3, q =4};
00128
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
00137 nav->orientation.roll = 0;
00138 nav->orientation.pitch = 0;
00139 nav->header.stamp = ros::Time::now();
00140 navsts.publish(nav);
00141
00142
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
00174
00175
00176
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 }