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
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
00099
00100
00101
00102
00103
00104
00105
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]);
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.;
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]);
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.;
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