Commit c00b215f authored by fmg005's avatar fmg005

Added pump client to talk to the rosbridge server

parent 8b8f7af6
#ifndef UDP_CLIENT_H
#define UDP_CLIENT_H
#include <sys/types.h>
#include <sys/socket.h> /* socket functions */
#include <sys/time.h> /* FD_SET, FD_ISSET, FD_ZERO, timeval, fd_set */
#include <sys/select.h>/* select() */
#include <stdio.h>
#include <stdlib.h> /* exit, EXIT_FAILURE */
#include <string.h> /* memcpy */
#include <unistd.h>
#include <netdb.h> /* gethostbyname */
#include <netinet/in.h>/* sockaddr_in */
#include <iostream>
#include "CLA_Logger.h"
#include "rapidjson/document.h"
using namespace rapidjson; /* third party library for parsing json data */
using namespace std;
namespace CLA {
class tcp_pump_client {
/* impementation of a non-blocking tcp client to talk
* to the rosbridge udp server
*/
private:
struct hostent *hp; /* host information */
struct sockaddr_in servaddr; /* server address information */
struct timeval timeout;
string json_message;
double m_current_rate;
double m_bpdrug_last_sent_rate;
double m_new_rate;
double m_saline_last_sent_rate;
double m_last_sent_rate;
string m_topic;
string m_type;
static const int BUFF_SIZE = 100;
char buff[BUFF_SIZE];
const char* m_host;
int port;
int fd, rec_value,recvlen;
int SOCKET_TIMEOUT_SEC;
int SOCKET_TIMEOUT_uSEC;
socklen_t addrlen;
Document document; /* to parse json data */
fd_set set; /* descriptor read set*/
CLA::LOGGER m_logger;
public:
tcp_pump_client();
tcp_pump_client(const string&, const string&);
~tcp_pump_client();
void initialize();
double getCurrentInfusionRate(const string&);
double get_new_rate(const string&);
double waiting_for_new_rate(const string&);
void clear();
};
}
#endif
......@@ -62,6 +62,9 @@ set( my_srcs
#example.cpp
SimulationEngine.cpp
Timer.cpp
tcp_pump_client.cpp
Action.cpp
Pump.cpp
)
add_executable(prosim ${my_srcs})
......@@ -69,6 +72,7 @@ add_executable(prosim ${my_srcs})
#include directories
target_include_directories(prosim PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/3rdParty/include
${serial_INCLUDE_DIR}
${Pulse_INCLUDE_DIRS}
${libconfig++_INCLUDE_DIR})
......@@ -80,3 +84,4 @@ target_link_libraries(prosim optimized
libconfig++
libserial)
install(TARGETS prosim DESTINATION ${Pulse_INSTALL}/bin)
#install(FILES ${Pulse_INSTALL}/bin/UCEDefs.txt DESITINATION ${CMAKE_CURRENT_SOURCE_DIR}/builds)
......@@ -11,7 +11,7 @@ prosim = {
simulation = {
time = {
run = 30.0; # Time -> Seconds How long should simulation run
injury_start = 10.0; # When should injury be introduced to patient
injury_start = 12.0; # When should injury be introduced to patient
injury_stop = 700.0; # When should injury be stopped
}
}
......
#include "tcp_pump_client.h"
using namespace CLA;
tcp_pump_client::tcp_pump_client() : m_logger() {
/* we can only talk to rosbrige server using json strings; here we want to
* 'subscribe' to 'chatter topic' publishing messages of type 'std_msgs/String'
*/
json_message = "{\"op\":\"subscribe\", \"topic\":\"/chatter\", \"type\":\"std_msgs/Float64\"}";
m_host = "localhost"; /* rosbridge server runs on localhost */
port = 9090; /* rosbridge server uses this port number */
SOCKET_TIMEOUT_SEC = 1;
SOCKET_TIMEOUT_uSEC = 500;
m_bpdrug_last_sent_rate = 0;
m_last_sent_rate = 0;
m_new_rate = 0;
m_current_rate = 0;
}
tcp_pump_client::tcp_pump_client(const string& topic, const string& type): m_topic(move(topic)),
m_type(move(type)), m_logger() {
json_message = "{\"op\":\"subscribe\", \"topic\": \""+m_topic+"\", \"type\": \""+m_type+"\"}";
m_host = "localhost"; /* rosbridge server runs on localhost */
port = 9090; /* rosbridge server uses this port number */
SOCKET_TIMEOUT_SEC = 1;
SOCKET_TIMEOUT_uSEC = 500;
m_bpdrug_last_sent_rate = 0;
m_last_sent_rate = 0;
m_new_rate = 0;
m_current_rate = 0;
}
void tcp_pump_client::initialize() {
/* create a UDP socket */
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
fprintf(stderr, "can not create socket\n");
m_logger.error("Failed to create socket");
exit(EXIT_FAILURE);
}
/* look up the address of the server given its name */
hp = gethostbyname(m_host);
if(!hp) {
fprintf(stderr, "could not obtain address %s\n", m_host);
exit(EXIT_FAILURE);
}
/* initialize sockaddr_in servaddr*/
memset((char*)&servaddr, 0, sizeof(servaddr));
/* connect to remote host (rosbridge_server in our case)*/
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port); /* convert to network byte order */
/* put host's address into th server address struct */
memcpy((void*)&servaddr.sin_addr, hp->h_addr_list[0], hp->h_length);
addrlen = sizeof(servaddr);
/* initialize buffer s*/
memset(buff, 0 , sizeof(buff));
/*connect to server */
if (connect(fd, (struct sockaddr*)&servaddr, addrlen) < 0) {
cout << "Connection Failed \n";
m_logger.error("TCP Connection Failed");
exit(EXIT_FAILURE);
}
/* send json message to server */
int n = write(fd, json_message.c_str(), strlen(json_message.c_str()));
if (n < 0) {
cout <<"Can not write to socket\n";
m_logger.error("Can not write to socket");
exit(EXIT_FAILURE);
}
}
double tcp_pump_client::getCurrentInfusionRate(const string& substance) {
timeout.tv_sec = SOCKET_TIMEOUT_SEC;
timeout.tv_usec = SOCKET_TIMEOUT_uSEC;
FD_ZERO(&set); /* initialize set */
FD_SET(fd, &set);/* add descriptor to the read set */
rec_value = select(FD_SETSIZE, &set, NULL, NULL, &timeout);
if (rec_value == -1 ) {
cout << "socket error\n";
exit(EXIT_FAILURE);
}
else if (rec_value == 0) {
/* on timeout -> keep calling the waiting_for_new_rate function
* to return the last sent value until topic publishes a new rate
*/
m_current_rate = waiting_for_new_rate(substance);
}
else {
m_current_rate = get_new_rate(substance);
}
return m_current_rate;
}
double tcp_pump_client::get_new_rate(const string& substance) {
recvlen = read(fd, buff, BUFF_SIZE);
if (recvlen > 0) {
buff[recvlen] = '\0'; /* adding EOL */
document.Parse(buff);
if (substance == "Norepinephrine") {
m_new_rate = document["msg"]["data"].GetDouble();
m_bpdrug_last_sent_rate = m_new_rate;
}
else if (substance == "Saline") {
m_new_rate = document["msg"]["data"].GetDouble();
m_saline_last_sent_rate = m_new_rate;
}
}
return m_new_rate;
}
double tcp_pump_client::waiting_for_new_rate(const string& substance) {
/* while topic is not publishing, keep
* returning the last sent rate value
*/
if (substance == "Norepinephrine") {
m_last_sent_rate = m_bpdrug_last_sent_rate;
}
else if (substance == "Saline") {
m_last_sent_rate = m_saline_last_sent_rate;
}
return m_last_sent_rate;
}
void tcp_pump_client::clear() {
hp = nullptr;
}
tcp_pump_client::~tcp_pump_client() {
close(fd);
clear();
delete hp;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment