spatial_world_model_server.cpp
Go to the documentation of this file.
00001 #include <spatial_world_model/spatial_world_model_server.h>
00002 
00003 #include <boost/algorithm/string.hpp>
00004 
00005 using namespace std;
00006 
00007 spatial_world_model_server::spatial_world_model_server() : private_("~")
00008 {
00009   // grab params
00010   private_.param("host", host_, string(SWM_DEFAULT_SERVER));
00011   private_.param("port", port_, SWM_DEFAULT_PORT);
00012   private_.param("user", user_, string(SWM_DEFAULT_USER));
00013   private_.param("password", password_, string(SWM_DEFAULT_PASSWORD));
00014   private_.param("database", database_, string(SWM_DEFAULT_DATABASE));
00015 
00016   // setup the client
00017   connected_ = false;
00018   conn_ = mysql_init(NULL);
00019   if (!mysql_real_connect(conn_, host_.c_str(), user_.c_str(), password_.c_str(), database_.c_str(), port_, NULL, 0))
00020   {
00021     ROS_ERROR("MySQL Error: %s", mysql_error(conn_));
00022     exit(EXIT_FAILURE);
00023   } else
00024   {
00025     connected_ = true;
00026   }
00027 
00028   // create the table if we need to
00029   MYSQL_RES *res = this->query(SWM_CREATE_TABLE);
00030   if (res)
00031   {
00032     mysql_free_result(res);
00033   }
00034 
00035   // setup ROS stuff
00036   store_observation_ = private_.advertiseService("store_observation", &spatial_world_model_server::store_observation_cb,
00037                                                  this);
00038   find_observations_ = private_.advertiseService("find_observations",
00039                                                  &spatial_world_model_server::find_observations_cb, this);
00040   set_observations_removed_ = private_.advertiseService("set_observations_removed",
00041                                                         &spatial_world_model_server::set_observations_removed_cb, this);
00042 
00043   ROS_INFO("Spatial World Model Initialized");
00044 }
00045 
00046 spatial_world_model_server::~spatial_world_model_server()
00047 {
00048   if (connected_)
00049   {
00050     mysql_close(conn_);
00051   }
00052 }
00053 
00054 
00055 bool spatial_world_model_server::set_observations_removed_cb(
00056     interactive_world_msgs::SetObservationsRemoved::Request & req,
00057     interactive_world_msgs::SetObservationsRemoved::Response & resp)
00058 {
00059   // convert into an SQL statement
00060   stringstream ss;
00061   ss << "UPDATE `" << SWM_TABLE "` SET `removed`=NOW() WHERE `id` IN (";
00062   for (size_t i = 0; i < req.ids.size(); i++)
00063   {
00064     ss << req.ids[i];
00065     if (i == req.ids.size() - 1)
00066     {
00067       ss << ")";
00068     } else
00069     {
00070       ss << ", ";
00071     }
00072   }
00073   ss << ";";
00074 
00075   string sql = ss.str();
00076   MYSQL_RES *res = this->query(sql);
00077   if (res)
00078   {
00079     mysql_free_result(res);
00080   }
00081 
00082   return true;
00083 }
00084 
00085 bool spatial_world_model_server::find_observations_cb(interactive_world_msgs::FindObservations::Request &req,
00086     interactive_world_msgs::FindObservations::Response &resp)
00087 {
00088   // convert into an SQL statement
00089   stringstream ss;
00090   ss << "SELECT * FROM `" << SWM_TABLE << "` WHERE (";
00091   if (!req.item.empty())
00092   {
00093     ss << "(UPPER(item) =\"" << boost::to_upper_copy(req.item) << "\") AND ";
00094   }
00095   if (!req.surface.empty())
00096   {
00097     ss << "(UPPER(surface) =\"" << boost::to_upper_copy(req.surface) << "\") AND ";
00098   }
00099   if (!req.surface_frame_id.empty())
00100   {
00101     ss << "(UPPER(surface_frame_id) =\"" << boost::to_upper_copy(req.surface_frame_id) << "\") AND ";
00102   }
00103   if (!req.placement_surface_frame_id.empty())
00104   {
00105     ss << "(UPPER(placement_surface_frame_id) =\"" << boost::to_upper_copy(req.placement_surface_frame_id) <<
00106     "\") AND ";
00107   }
00108   if (req.removed)
00109   {
00110     ss << "(removed > '0000-00-00 00:00:00')) ";
00111   } else
00112   {
00113     ss << "(removed >= '0000-00-00 00:00:00')) ";
00114   }
00115   ss << "ORDER BY `time` DESC;";
00116   string query = ss.str();
00117 
00118   MYSQL_RES *res = this->query(query);
00119   if (res)
00120   {
00121     MYSQL_ROW row;
00122     while ((row = mysql_fetch_row(res)) != NULL)
00123     {
00124       resp.ids.push_back(atoi(row[0]));
00125       resp.surfaces.push_back(string(row[1]));
00126       resp.surface_frame_ids.push_back(string(row[2]));
00127       resp.placement_surface_frame_ids.push_back(string(row[3]));
00128       resp.items.push_back(string(row[4]));
00129       resp.item_confs.push_back(atof(row[5]));
00130       resp.xs.push_back(atof(row[6]));
00131       resp.ys.push_back(atof(row[7]));
00132       resp.zs.push_back(atof(row[8]));
00133       resp.thetas.push_back(atof(row[9]));;
00134       resp.times.push_back(ros::Time(this->extract_time(row[10]), 0));
00135       resp.removals.push_back(ros::Time(this->extract_time(row[11]), 0));
00136     }
00137     mysql_free_result(res);
00138   }
00139 
00140   if (resp.surfaces.empty())
00141   {
00142     ROS_WARN("No instances of %s found in the spatial world model.", req.item.c_str());
00143   }
00144 
00145   return true;
00146 }
00147 
00148 bool spatial_world_model_server::store_observation_cb(interactive_world_msgs::StoreObservation::Request &req,
00149     interactive_world_msgs::StoreObservation::Response &resp)
00150 {
00151   // convert into an SQL statement
00152   stringstream ss;
00153   ss << "INSERT INTO `" << SWM_TABLE << "`"
00154   << "(`surface`, `surface_frame_id`, `placement_surface_frame_id`, `item`, `item_conf`, `x`, `y`, `z`, `theta`)"
00155   << "VALUES ("
00156   << "\"" << req.surface << "\", "
00157   << "\"" << req.surface_frame_id << "\", "
00158   << "\"" << req.placement_surface_frame_id << "\", "
00159   << "\"" << req.item << "\", "
00160   << "" << req.item_conf << ", "
00161   << "" << req.x << ", "
00162   << "" << req.y << ", "
00163   << "" << req.z << ", "
00164   << "" << req.theta
00165   << ");";
00166 
00167   MYSQL_RES *res = this->query(ss.str());
00168   if (res)
00169   {
00170     mysql_free_result(res);
00171   }
00172 
00173   return true;
00174 }
00175 
00176 bool spatial_world_model_server::connected()
00177 {
00178   return connected_;
00179 }
00180 
00181 MYSQL_RES *spatial_world_model_server::query(string query)
00182 {
00183   if (mysql_query(conn_, query.c_str()) == 0)
00184   {
00185     // parse and get it
00186     return mysql_use_result(conn_);
00187   } else
00188   {
00189     ROS_ERROR("MySQL Error: %s", mysql_error(conn_));
00190   }
00191 
00192   // something went wrong
00193   return NULL;
00194 }
00195 
00196 time_t spatial_world_model_server::extract_time(const string &str) const
00197 {
00198   if (str == "0000-00-00 00:00:00")
00199   {
00200     return 0;
00201   }
00202   // set values we don't need to be 0
00203   struct tm t;
00204   bzero(&t, sizeof(t));
00205   sscanf(str.c_str(), "%d-%d-%d %d:%d:%d", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec);
00206   // correct the information for C time
00207   t.tm_year -= 1900;
00208   t.tm_mon -= 1;
00209   // daylight savings crap
00210   t.tm_hour -= 1;
00211   return mktime(&t);
00212 }
00213 
00214 int main(int argc, char **argv)
00215 {
00216   // initialize ROS and the node
00217   ros::init(argc, argv, "spatial_world_model_server");
00218   spatial_world_model_server server;
00219   ros::spin();
00220 }


spatial_world_model
Author(s): Russell Toris
autogenerated on Thu Jun 6 2019 21:34:31