ocra-recipes
Doxygen documentation for the ocra-recipes repository
ClientCommunications.cpp
Go to the documentation of this file.
2 
3 
4 using namespace ocra_recipes;
5 
6 int ClientCommunications::CONTROLLER_CLIENT_COUNT = 0;
7 
8 
10 : inputCallback(*this)
11 {
12  clientNumber = ++ClientCommunications::CONTROLLER_CLIENT_COUNT;
13 
14  while(yarp.exists(("/ControllerClient/"+ std::to_string(clientNumber) +"/rpc:o")))
15  {
16  ++clientNumber;
17  }
18 
19  rpcClientPort_Name = "/ControllerClient/"+ std::to_string(clientNumber) +"/rpc:o";
20  inputPort_Name = "/ControllerClient/"+ std::to_string(clientNumber) +":i";
21 }
22 
24 {
25  close();
26  --ClientCommunications::CONTROLLER_CLIENT_COUNT;
27 }
28 
29 bool ClientCommunications::open(double timeout, bool connectToTasks)
30 {
31  rpcClientPort.open(rpcClientPort_Name.c_str());
32  rpcClientPort.setReader(*this);
33  inputPort.open(inputPort_Name.c_str());
34  inputPort.setReader(inputCallback);
35 
36  bool isConOpen = openServerConnections(timeout);
37  if(isConOpen && connectToTasks)
38  {
39  isConOpen &= openTaskConnections();
40 
41  if(isConOpen)
42  {
43  for(auto rpc_i : taskRpcClients)
44  {
45  yarp::os::Bottle message, reply;
47  rpc_i.second->write(message, reply);
48  }
49  }else{
50  yLog.error() << "Couldn't connect to the individual task ports.";
51  }
52  }
53  return isConOpen;
54 }
55 
56 std::vector<std::string> ClientCommunications::getTaskTypes()
57 {
58  std::vector<std::string> retVec;
59  for(auto rpc_i : taskRpcClients)
60  {
61  yarp::os::Bottle message, reply;
63  rpc_i.second->write(message, reply);
64  retVec.push_back(reply.get(0).asString());
65  }
66  return retVec;
67 }
68 
70 {
71  rpcClientPort.close();
72  inputPort.close();
73 
74  for(auto rpc_i : taskRpcClients)
75  {
76  rpc_i.second->close();
77  }
78  taskRpcClients.clear();
79  return true;
80 }
81 
82 void ClientCommunications::close(const std::string& taskName)
83 {
84  if(taskRpcClients.find(taskName) != taskRpcClients.end())
85  {
86  taskRpcClients[taskName]->close();
87  taskRpcClients.erase(taskName);
88  }
89 }
90 
91 bool ClientCommunications::read(yarp::os::ConnectionReader& connection)
92 {
93  yarp::os::Bottle input;
94 
95  if (!input.read(connection)){
96  return false;
97  }
98  else{
99  parseMessage(input);
100  return true;
101  }
102 }
103 
104 bool ClientCommunications::openServerConnections(double timeout)
105 {
106  if (!yarp.checkNetwork()) {
107  yLog.error() << "Yarp network isn't running.";
108  return false;
109  }
110  else{
111  bool connected = false;
112  double timeDelayed = 0.0;
113  double delayTime = 0.01;
114  while(!connected && (timeDelayed < timeout))
115  {
116  connected = yarp.connect(rpcClientPort_Name.c_str(), "/ControllerServer/rpc:i");
117  yarp::os::Time::delay(delayTime);
118  timeDelayed += delayTime;
119  if (timeDelayed>= timeout) {
120  yLog.error() << "Could not connect to the ocra controller server. Are you sure it is running?";
121  }
122  }
123 
124  // connected = false;
125  // timeDelayed = 0.0;
126  // while(!connected && timeDelayed < timeout)
127  // {
128  // connected = yarp.connect("/ControllerServer:o", inputPort_Name.c_str());
129  // yarp::os::Time::delay(delayTime);
130  // timeDelayed += delayTime;
131  // if (timeDelayed>= timeout) {
132  // yLog.error() << "Could not connect to the ocra controller port. Are you sure it is running?";
133  // }
134  // }
135  return connected;
136  }
137 }
138 std::vector<std::string> ClientCommunications::getTaskPortNames()
139 {
140  std::vector<std::string> portNameVec;
141  yarp::os::Bottle message, reply;
142  message.addInt(GET_TASK_PORT_LIST);
143  rpcClientPort.write(message, reply);
144  for(auto i=0; i<reply.size(); ++i)
145  {
146  portNameVec.push_back(reply.get(i).asString());
147  }
148  return portNameVec;
149 }
150 
151 std::string ClientCommunications::getTaskPortName(const std::string& taskName)
152 {
153  yarp::os::Bottle message, reply;
154  message.addInt(GET_TASK_PORT_NAME);
155  message.addString(taskName);
156  rpcClientPort.write(message, reply);
157 
158  std::string portName = "";
159  if (reply.size()>0) {
160  portName = reply.get(0).asString();
161  }
162  return portName;
163 }
164 
165 std::vector<std::string> ClientCommunications::getTaskNames()
166 {
167  std::vector<std::string> nameVec;
168  yarp::os::Bottle message, reply;
169  message.addInt(GET_TASK_LIST);
170  rpcClientPort.write(message, reply);
171  for(auto i=0; i<reply.size(); ++i)
172  {
173  nameVec.push_back(reply.get(i).asString());
174  }
175  return nameVec;
176 }
177 
178 std::shared_ptr<yarp::os::RpcClient> ClientCommunications::getTaskClient(const std::string& taskName)
179 {
180  if(taskRpcClients.find(taskName) != taskRpcClients.end())
181  {
182  return taskRpcClients[taskName];
183  }else{
184  //TODO: return a proper null pointer.
185  }
186 }
187 
188 
189 yarp::os::Bottle ClientCommunications::queryController(yarp::os::Bottle& requestBottle)
190 {
191  yarp::os::Bottle reply;
192  rpcClientPort.write(requestBottle, reply);
193  return reply;
194 }
195 
197 {
198  yarp::os::Bottle requestBottle, reply;
199  requestBottle.addInt(request);
200  rpcClientPort.write(requestBottle, reply);
201  return reply;
202 }
203 
204 yarp::os::Bottle ClientCommunications::queryController(const std::vector<SERVER_COMMUNICATIONS_MESSAGE> requestVector)
205 {
206  yarp::os::Bottle requestBottle, reply;
207  for(auto request : requestVector){
208  requestBottle.addInt(request);
209  }
210  rpcClientPort.write(requestBottle, reply);
211  return reply;
212 }
213 
214 bool ClientCommunications::openTaskConnections()
215 {
216  std::vector<std::string> taskNames = getTaskNames();
217  std::vector<std::string> taskPortNames = getTaskPortNames();
218 
219  bool taskConnected = taskNames.size() == taskPortNames.size();
220 
221  if(taskConnected)
222  {
223  for(auto i=0; i<taskPortNames.size(); ++i)
224  {
225  std::string tmpTaskPortName = "/ControllerClient/" + std::to_string(clientNumber) + "/" + taskNames[i] + ":o";
226  taskRpcClients[taskNames[i]] = std::make_shared<yarp::os::RpcClient>();
227  taskRpcClients[taskNames[i]]->open(tmpTaskPortName.c_str());
228  taskConnected &= yarp.connect(tmpTaskPortName.c_str(), taskPortNames[i].c_str());
229  }
230  }else{
231  yLog.error() << "The number of task ports and names does not match! Can't connect to task RPC ports.";
232  }
233 
234  return taskConnected;
235 }
236 
237 void ClientCommunications::parseMessage(yarp::os::Bottle& input)
238 {
239  int btlSize = input.size();
240  for (int i=0; i<btlSize;)
241  {
242  switch (input.get(i).asInt()) {
243  case REMOVE_TASK_PORT:
244  {
245  ++i;
246  std::cout << "Got message: REMOVE_TASK_PORT - " << input.get(i).asString() << std::endl;
247  close(input.get(i).asString());
248  ++i;
249  }break;
250 
251  case HELP:
252  {
253  ++i;
254  std::cout << "Got message: HELP." << std::endl;
255  }break;
256 
257  default:
258  {
259  ++i;
260  std::cout << "Got message: UNKNOWN." << std::endl;
261  }break;
262 
263  }
264  }
265 }
266 
267 
269 : coms(comsRef)
270 {
271  //
272 }
273 
274 bool ClientCommunications::InputCallback::read(yarp::os::ConnectionReader& connection)
275 {
276  yarp::os::Bottle input;
277  if (input.read(connection)){
278  return coms.parseInput(input);
279  }
280  else{
281  return false;
282  }
283 }
284 
285 bool ClientCommunications::parseInput(yarp::os::Bottle& input)
286 {
287  int btlSize = input.size();
288  for (auto i=0; i<btlSize; ++i) {
289  switch (input.get(i).asInt()) {
290 
291  case REMOVE_TASK_PORT:
292  {
293  ++i;
294  yLog.info() << "Removing task " << input.get(i).asString();
295  close(input.get(i).asString());
296  }break;
297 
298  default:
299  break;
300  }
301  }
302  return true;
303 }
void parseMessage(yarp::os::Bottle &input)
virtual bool read(yarp::os::ConnectionReader &connection)
std::vector< std::string > getTaskTypes()
yarp::os::Bottle queryController(yarp::os::Bottle &requestBottle)
std::vector< std::string > getTaskNames()
virtual bool read(yarp::os::ConnectionReader &connection)
bool parseInput(yarp::os::Bottle &input)
bool open(double timeout=20.0, bool connectToTasks=true)
std::vector< std::string > getTaskPortNames()
std::shared_ptr< yarp::os::RpcClient > getTaskClient(const std::string &taskName)
std::string getTaskPortName(const std::string &taskName)