Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
exporterSocket.hpp
00001 
00013 #ifndef EXPORTER_SOCKET_HPP_
00014 #define EXPORTER_SOCKET_HPP_
00015 
00016 #include <boost/asio.hpp>
00017 #include <boost/thread.hpp>
00018 #include <boost/bind.hpp>
00019 
00020 #include "kernel/threads.hpp"
00021 
00022 #include "rtslam/exporterAbstract.hpp"
00023 
00024 namespace jafar {
00025 namespace rtslam {
00026 
00027   
00028   using boost::asio::ip::tcp;
00029   typedef boost::shared_ptr<tcp::socket> socket_ptr;
00030   
00031   class ExporterSocket: public ExporterAbstract
00032   {
00033     protected:
00034       void connectionTask()
00035       {
00036         boost::asio::io_service io_service;
00037         tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port));
00038         while (true)
00039         {
00040           // wait for new connection
00041           socket_ptr mysock(new tcp::socket(io_service));
00042           a.accept(*mysock);
00043           std::cout << "ExporterSocket: new client connected." << std::endl;
00044           
00045           boost::unique_lock<boost::mutex> l(mutex_data);
00046           socks.push_back(mysock);
00047         }
00048         
00049       }
00050   
00051       void sendTask()
00052       {
00053         bool stop = false;
00054         while (!stop)
00055         {
00056           condition_send.wait(boost::lambda::_1 != 0, false);
00057           if (condition_send.var < 0) stop = true;
00058           condition_send.var = 0;
00059           condition_send.unlock();
00060           if (stop) break;
00061           
00062           boost::unique_lock<boost::mutex> l(mutex_data);
00063           bool remove_sock = false;
00064           for(std::vector<socket_ptr>::iterator it = socks.begin(); it != socks.end(); it = (remove_sock ? socks.erase(it) : it+1))
00065           {
00066             remove_sock = false;
00067             try {
00068               boost::asio::write(**it, boost::asio::buffer(message, message_size*sizeof(double)));
00069             } catch (std::exception &e)
00070             {
00071               std::cout << "client disconnected" << std::endl;
00072               remove_sock = true;
00073             }
00074           }
00075         }
00076       }
00077       
00078       boost::mutex mutex_data;
00079       kernel::VariableCondition<int> condition_send;
00080       
00081       static const int message_size = 25;
00082       short port;
00083       std::vector<socket_ptr> socks;
00084       double message[message_size];
00085       
00086     public:
00087       ExporterSocket(robot_ptr_t robPtr, short port): ExporterAbstract(robPtr),
00088         condition_send(0), port(port)
00089       {
00090         boost::thread thread_connection(boost::bind(&ExporterSocket::connectionTask, this));
00091         boost::thread thread_send(boost::bind(&ExporterSocket::sendTask, this));
00092       }
00093       
00094       virtual void exportCurrentState()
00095       {
00096         if (mutex_data.try_lock())
00097         {
00098           // FIXME works only for inertial, should be fixed with the general state framework
00099           /*
00100           (1 double)   time
00101           (12 double) pos(x,y,z) euler(yaw,pitch,roll)
00102           vel(vx,vy,vz) avel(vyaw,vpitch,vroll)
00103           (12 double) variances
00104           
00105           robot : p q v ab wb g
00106           */
00107           jblas::vec state(6); jblas::sym_mat state_P(6,6);
00108           jblas::vec stateq_x = robPtr->pose.x();
00109           jblas::sym_mat stateq_P = robPtr->pose.P();
00110           robPtr->slamPoseToRobotPose(stateq_x, stateq_P, state, state_P);
00111 
00112           message[0] = robPtr->self_time;
00113           for(int i = 0; i < 6; ++i) message[i+1] = state(i);
00114           std::swap(message[3+1], message[5+1]); // convention roll/pitch/yaw to yaw/pitch/roll
00115           for(int i = 6; i < 9; ++i) message[i+1] = robPtr->mapPtr()->filterPtr->x(i);
00116           for(int i = 9; i < 12; ++i) message[i+1] = 0.; // TODO get value from MTI, with some "non filtered state" feature
00117           
00118           for(int i = 0; i < 6; ++i) message[i+1+12] = sqrt(state_P(i,i));
00119           std::swap(message[3+1+12], message[5+1+12]); // convention roll/pitch/yaw to yaw/pitch/roll
00120           for(int i = 6; i < 9; ++i) message[i+1+12] = sqrt(robPtr->mapPtr()->filterPtr->P(i,i));
00121           for(int i = 9; i < 12; ++i) message[i+1+12] = 0.; // TODO get value from MTI, with some "non filtered state" feature
00122           
00123           mutex_data.unlock();
00124           condition_send.setAndNotify(1);
00125         } else
00126           std::cout << "ExporterSocket: not finished sending previous message, connect less clients!" << std::endl;
00127       }
00128       
00129       virtual void stop() { condition_send.setAndNotify(-1); }
00130   };
00131   
00132 
00133 }}
00134 
00135 
00136 #endif // EXPORTERSOCKET_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:26 for Jafar by doxygen 1.7.6.1
LAAS-CNRS