modbridge_node.cpp
Go to the documentation of this file.
1 
15 #include <ros/ros.h>
16 #include <modelica_bridge/ModComm.h>
17 
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <sys/un.h>
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <netinet/in.h>
24 #include <signal.h>
25 #include <functional>
26 
27 #include <stdlib.h>
28 #include <string.h>
29 
36 #define MAX_BUF 1024 // define maximum length of character buffer
37 #define MAX_ARRAY 256 // define maximum size of internal buffer arrays
38 
44 class ModBridge
45 {
46  public:
52  ModBridge();
59  void spin();
60 
61  private:
69  void controllerCallback(const modelica_bridge::ModComm::ConstPtr& inVal);
70 
80  void readFromBuffer();
81 
89  void writeToBuffer();
90 
97  void error(const char *msg);
98 
102 
105  int port_num_;
106  struct sockaddr_in serv_addr;
107  socklen_t client_len_;
108  struct sockaddr_in client_address_;
109 
110  char buffer_[MAX_BUF];
114 
116 };
117 
119 {
120  sub_ = nh_.subscribe("control_values", 1, &ModBridge::controllerCallback, this);
121  pub_ = nh_.advertise<modelica_bridge::ModComm>("model_values", 1);
122 
123  ros::NodeHandle nh_param("~");
124  nh_param.param<int>("port_num", port_num_, 9091);
125  nh_param.param<int>("update_rate", update_rate_, 20);
126 
127  socket_fd_ = socket(AF_INET, SOCK_STREAM, 0);
128  if (socket_fd_ < 0) {
129  error("ERROR opening socket");
130  }
131 
132  bzero((char *) &serv_addr, sizeof(serv_addr));
133 
134  serv_addr.sin_family = AF_INET;
135  serv_addr.sin_addr.s_addr = INADDR_ANY;
136  serv_addr.sin_port = htons(port_num_);
137  if (bind(socket_fd_, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
138  error("ERROR on binding");
139  }
140 }
141 
143 {
144  ros::Rate loop(update_rate_);
145 
146  while(ros::ok())
147  {
148  modelica_bridge::ModComm outVal;
149 
150  listen(socket_fd_,5);
151  client_len_ = sizeof(client_address_);
152 
153  new_socket_fd_ = accept(socket_fd_, (struct sockaddr *) &client_address_, &client_len_);
154  if (new_socket_fd_ < 0) {
155  error("ERROR on accept");
156  }
157 
159  if (error_check_ < 0) {
160  error("ERROR reading from socket");
161  }
162 
163  readFromBuffer();
164  writeToBuffer();
165 
166  error_check_ = write(new_socket_fd_, buffer_, strlen(buffer_));
167  if (error_check_ < 0) {
168  error("ERROR writing to socket");
169  }
170 
171  close(new_socket_fd_);
172 
173  outVal.data.clear();
174  outVal.size = ros_buffer_[0];
175  for (int rosI = 1; rosI <= outVal.size; rosI ++) {
176  outVal.data.push_back(ros_buffer_[rosI]);
177  }
178  pub_.publish(outVal);
179 
180  ros::spinOnce();
181  loop.sleep();
182  }
183  close(socket_fd_);
184 }
185 
186 void ModBridge::controllerCallback(const modelica_bridge::ModComm::ConstPtr& inVal)
187 {
188  int i;
189  for(i = 0; i < inVal->size; i++) {
190  socket_buffer_[i] = inVal->data[i];
191  }
192 }
193 
195 {
196  int j, i = 0;
197  char *token[80];
198  const char * delim = ",";
199 
200  token[0] = strtok(buffer_, delim);
201  while (token[i] != NULL) {
202  i++;
203  token[i] = strtok(NULL, delim);
204  }
205 
206  for (j=0; j<=i-1; j++) {
207  ros_buffer_[j] = atof(token[j]);
208  }
209 }
210 
212 {
213  buffer_[0] = '\0';
214  char s1[100];
215  for (int i = 0; i< sizeof(*socket_buffer_); i++)
216  {
217  sprintf(s1,"%f,",socket_buffer_[i]);
218  strcat(buffer_,s1);
219  }
220 }
221 
222 void ModBridge::error(const char *msg)
223 {
224  perror(msg);
225  exit(1);
226 }
227 
228 int main(int argc, char** argv)
229 {
230  ros::init(argc, argv, "modros_node");
231 
232  ModBridge modbridge;
233 
234  modbridge.spin();
235 
236  return 0;
237 }
msg
int new_socket_fd_
Modelica socket binding.
double ros_buffer_[MAX_ARRAY]
buffer array for transmission via ROS
int main(int argc, char **argv)
#define MAX_BUF
Defines the maximum length of the character buffer.
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
char buffer_[MAX_BUF]
string buffer used to transmit information over the socket
int update_rate_
ROS node maximum loop rate.
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ros::Publisher pub_
publisher for model feedback values
ros::NodeHandle nh_
ROS node handle.
int error_check_
Parameter for checking errors on socket interaction.
struct sockaddr_in serv_addr
ROS socket address.
#define MAX_ARRAY
Defines the maximum size of internal buffer arrays.
socklen_t client_len_
Modelica socket size.
void controllerCallback(const modelica_bridge::ModComm::ConstPtr &inVal)
struct sockaddr_in client_address_
Modelica socket address.
int socket_fd_
ROS socket binding.
ROSCPP_DECL bool ok()
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool sleep()
double socket_buffer_[MAX_ARRAY]
buffer array for interaction with socket
void error(const char *msg)
int port_num_
Port number.
ROSCPP_DECL void spinOnce()
ros::Subscriber sub_
subscriber to ROS controller values
void writeToBuffer()
void readFromBuffer()


modelica_bridge
Author(s):
autogenerated on Mon Jun 10 2019 13:54:27