MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
test_modalext_socket.c
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/utils/test_modalext_socket.c,v 1.16 2017/01/12 15:10:28 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 #include <stdlib.h>
33 #include <stdint.h>
34 #include <stdio.h>
35 #include <signal.h>
36 #include <unistd.h>
37 #include <string.h>
38 
39 /*
40  * NOTE: this is all we use from MBDyn. It was intentionally designed
41  * to be configuration-independent.
42  */
43 #include "mbc.h"
44 
45 /* test tool specific stuff */
46 static volatile sig_atomic_t keep_going = 1;
47 
48 static void
49 sh(int signum)
50 {
51  keep_going = 0;
52  signal(signum, SIG_DFL);
53 }
54 
55 void
56 usage(void)
57 {
58  fprintf(stderr,
59  "usage: testsocket [options]\n"
60  "\t-c [random:]<c>\tnumber of iterations\n"
61  "\t-f {fx,fy,fz,mx,my,mz} reference node force/moment\n"
62  "\t-H <url>\tURL (local://path | inet://host:port)\n"
63  "\t-M <modes>\tmodes number\n"
64  "\t-p {p1,...,pM}\tmodal forces (need -M first)\n"
65  "\t-r\t\tuse reference node data\n"
66  "\t-s <sleeptime>\tsleep time between tries\n"
67  "\t-v\t\tverbose\n"
68  "\t-x\t\tdata_and_next\n");
69  exit(EXIT_FAILURE);
70 }
71 
72 int
73 main(int argc, char *argv[])
74 {
75  int sleeptime = 1;
76  int iters = 1;
77  int iters_random = 0;
78  unsigned steps;
79 
80  char *path = NULL;
81  char *host = NULL;
82  unsigned short int port = -1;
83 
84  int refnode = 0;
85  unsigned modes = 0;
86 
87  mbc_modal_t mbcx = { { 0 } };
88  mbc_modal_t *mbc = &mbcx;
89 
90  double fx[6], *f0 = NULL;
91  double *p0 = NULL;
92 
93  while (1) {
94  int opt = getopt(argc, argv, "c:f:H:M:p:rs:vx");
95 
96  if (opt == EOF) {
97  break;
98  }
99 
100  switch (opt) {
101  case 'c':
102  if (strncasecmp(optarg, "random:", sizeof("random:") -1) == 0) {
103  iters_random = 1;
104  iters = atoi(&optarg[sizeof("random:") -1]);
105 
106  } else {
107  iters = atoi(optarg);
108  printf("iterations: %d\n", iters);
109  }
110  if (iters < 1) {
111  fprintf(stderr, "test_modalext_socket: "
112  "invalid iterations %s\n",
113  optarg);
114  usage();
115  }
116  break;
117 
118  case 'f': {
119  char *s;
120  int i;
121 
122  if (f0 != NULL) {
123  fprintf(stderr, "test_modalext_socket: "
124  "-f already provided\n");
125  usage();
126  }
127 
128  f0 = fx;
129 
130  s = optarg;
131  for (i = 0; i < 6; i++) {
132  char *next;
133 
134  f0[i] = strtod(s, &next);
135  if (next == s) {
136  fprintf(stderr, "test_modalext_socket: "
137  "unable to parse f[%d]\n", i);
138  usage();
139  }
140 
141  if (i < 5) {
142  if (next[0] != ',') {
143  fprintf(stderr, "test_modalext_socket: "
144  "unable to parse past f[%d]\n", i);
145  usage();
146  }
147 
148  s = &next[1];
149 
150  } else {
151  if (next[0] != '\0') {
152  fprintf(stderr, "test_modalext_socket: "
153  "extra cruft past f[%d]\n", i);
154  usage();
155  }
156  }
157  }
158  } break;
159 
160  case 'H':
161  if (strncasecmp(optarg, "inet://", sizeof("inet://") - 1) == 0) {
162  char *ptr, *next;
163  long l;
164 
165  host = optarg + sizeof("inet://") - 1;
166  ptr = strchr(host, ':');
167  if (ptr == NULL) {
168  usage();
169  }
170  *ptr = '\0';
171  ptr++;
172  l = strtol(ptr, &next, 10);
173  if (next == ptr || next[0] != '\0') {
174  usage();
175  }
176  if (l <= 0) {
177  usage();
178  }
179  port = (unsigned short)l;
180 
181  } else if (strncasecmp(optarg, "local://", sizeof("local://") - 1) == 0) {
182  path = optarg + sizeof("local://") - 1;
183  if (path[0] != '/') {
184  usage();
185  }
186 
187  } else {
188  usage();
189  }
190 
191  break;
192 
193  case 'M': {
194  int imodes;
195 
196  if (p0 != NULL) {
197  fprintf(stderr, "test_modalext_socket: "
198  "-M cannot follow -p\n");
199  usage();
200  }
201 
202  imodes = atoi(optarg);
203  if (imodes <= 0) {
204  fprintf(stderr, "test_modalext_socket: "
205  "invalid mode number %s\n",
206  optarg);
207  usage();
208  }
209  modes = (unsigned)imodes;
210  } break;
211 
212  case 'p': {
213  char *s;
214  int i;
215 
216  if (p0 != NULL) {
217  fprintf(stderr, "test_modalext_socket: "
218  "-p already provided\n");
219  usage();
220  }
221 
222  if (modes == 0) {
223  fprintf(stderr, "test_modalext_socket: "
224  "-p requires -M\n");
225  usage();
226  }
227 
228  p0 = (double *)calloc(sizeof(double), modes);
229  if (p0 == NULL) {
230  fprintf(stderr, "test_modalext_socket: "
231  "malloc for modal force values failed\n");
232  exit(EXIT_FAILURE);
233  }
234 
235  s = optarg;
236  for (i = 0; i < modes; i++) {
237  char *next;
238 
239  p0[i] = strtod(s, &next);
240  if (next == s) {
241  fprintf(stderr, "test_modalext_socket: "
242  "unable to parse p[%d]\n", i);
243  usage();
244  }
245 
246  if (i < modes - 1) {
247  if (next[0] != ',') {
248  fprintf(stderr, "test_modalext_socket: "
249  "unable to parse past p[%d]\n", i);
250  usage();
251  }
252 
253  s = &next[1];
254 
255  } else {
256  if (next[0] != '\0') {
257  fprintf(stderr, "test_modalext_socket: "
258  "extra cruft past p[%d]\n", i);
259  usage();
260  }
261  }
262  }
263  } break;
264 
265  case 'r':
266  refnode = 1;
267  break;
268 
269  case 's':
270  sleeptime = atoi(optarg);
271  if (sleeptime < 0) {
272  fprintf(stderr, "test_modalext_socket: "
273  "invalid iters %s\n",
274  optarg);
275  usage();
276  }
277  break;
278 
279  case 'v':
280  mbc->mbc.verbose = 1;
281  break;
282 
283  case 'x':
284  mbc->mbc.data_and_next = 1;
285  break;
286 
287  default:
288  usage();
289  }
290  }
291 
292  if (path) {
293  if (mbc_unix_init((mbc_t *)mbc, path)) {
294  exit(EXIT_FAILURE);
295  }
296 
297  } else if (host) {
298  if (mbc_inet_init((mbc_t *)mbc, host, port)) {
299  exit(EXIT_FAILURE);
300  }
301 
302  } else {
303  usage();
304  }
305 
306  if (mbc_modal_init(mbc, refnode, modes)) {
307  exit(EXIT_FAILURE);
308  }
309 
310  if (mbc_modal_negotiate_request(mbc)) {
311  exit(EXIT_FAILURE);
312  }
313 
314  signal(SIGTERM, sh);
315  signal(SIGINT, sh);
316 
317  for (steps = 0; keep_going > 0; steps++) {
318  int iter;
319  int niters;
320 
321  if (iters_random) {
322  niters = rand() % iters + 1;
323  printf(" iterations within this iter: %d\n", niters);
324 
325  } else {
326  niters = iters;
327  }
328 
329  for (iter = 0; iter < niters; iter++) {
330  if (mbc_modal_get_motion(mbc)) {
331  goto done;
332  }
333 
334  if (refnode && mbc->mbc.verbose) {
335  double *x = MBC_R_X(mbc);
336  double *r;
337  double *v = MBC_R_XP(mbc);
338  double *w = MBC_R_OMEGA(mbc);
339 
340  fprintf(stdout, "x={%+16.8e,%+16.8e,%+16.8e}\n", x[0], x[1], x[2]);
341  switch (MBC_F_ROT(mbc)) {
342  case MBC_ROT_THETA:
343  r = MBC_R_THETA(mbc);
344  fprintf(stdout, "t={%+16.8e,%+16.8e,%+16.8e};\n", r[0], r[1], r[2]);
345  break;
346 
347  case MBC_ROT_MAT:
348  r = MBC_R_R(mbc);
349  fprintf(stdout, "R={{%+16.8e,%+16.8e,%+16.8e};\n", r[0], r[3], r[6]);
350  fprintf(stdout, " {%+16.8e,%+16.8e,%+16.8e};\n", r[1], r[4], r[7]);
351  fprintf(stdout, " {%+16.8e,%+16.8e,%+16.8e}};\n", r[2], r[5], r[8]);
352  break;
353 
354  case MBC_ROT_EULER_123:
355  r = MBC_R_EULER_123(mbc);
356  fprintf(stdout, "e={%+16.8e,%+16.8e,%+16.8e};\n", r[0], r[1], r[2]);
357  break;
358  }
359  fprintf(stdout, "v={%+16.8e,%+16.8e,%+16.8e}\n", v[0], v[1], v[2]);
360  fprintf(stdout, "w={%+16.8e,%+16.8e,%+16.8e}\n", w[0], w[1], w[2]);
361  }
362 
363  if (modes > 0 && mbc->mbc.verbose) {
364  double *q = MBC_Q(mbc);
365  double *qp = MBC_QP(mbc);
366  int m;
367 
368  for (m = 0; m < modes; m++) {
369  fprintf(stdout, "mode #%d: %+16.8e %+16.8e\n", m, q[m], qp[m]);
370  }
371  }
372 
373  if (sleeptime) {
374  sleep(sleeptime);
375  }
376 
377  /* set forces */
378  if (refnode) {
379  double *f = MBC_R_F(mbc);
380  double *m = MBC_R_M(mbc);
381 
382  if (f0 != NULL) {
383  f[0] = f0[0];
384  f[1] = f0[1];
385  f[2] = f0[2];
386 
387  m[0] = f0[3];
388  m[1] = f0[4];
389  m[2] = f0[5];
390 
391  } else {
392  f[0] = 1.;
393  f[1] = 2.;
394  f[2] = 3.;
395 
396  m[0] = 4.;
397  m[1] = 5.;
398  m[2] = 6.;
399  }
400  }
401 
402  if (modes > 0) {
403  double *p = MBC_P(mbc);
404  int m;
405 
406  if (p0) {
407  for (m = 0; m < modes; m++) {
408  p[m] = p0[m];
409  }
410 
411  } else {
412  for (m = 0; m < modes; m++) {
413  p[m] = (double)(m + 1);
414  }
415  }
416  }
417 
418  if (mbc_modal_put_forces(mbc, (iter == niters - 1))) {
419  goto done;
420  }
421  }
422  }
423 
424 done:;
425  mbc_modal_destroy(mbc);
426 
427  if (p0) {
428  free(p0);
429  }
430 
431  return 0;
432 }
nodal stuff (partially opaque).
Definition: mbc.h:509
static int iters
#define MBC_P(mbc)
Definition: mbc.h:518
int mbc_modal_destroy(mbc_modal_t *mbc)
Destroy modal data.
static double * f0
int verbose
Definition: mbc.h:128
#define MBC_R_OMEGA(mbc)
Definition: mbc.h:288
int main(int argc, char *argv[])
static double * p0
#define MBC_QP(mbc)
Definition: mbc.h:517
static int iters_random
char data_and_next
Definition: mbc.h:125
#define MBC_R_M(mbc)
Definition: mbc.h:293
#define MBC_R_XP(mbc)
Definition: mbc.h:287
#define MBC_Q(mbc)
Definition: mbc.h:516
int mbc_modal_negotiate_request(mbc_modal_t *mbc)
Negotiate modal data.
const char * host
Definition: autopilot.c:142
static double fx[6]
int mbc_modal_init(mbc_modal_t *mbc, int refnode, unsigned modes)
Initialize modal data.
#define MBC_F_ROT(mbc)
Definition: mbc.h:243
Connection data structure (partially opaque)
Definition: mbc.h:103
static volatile sig_atomic_t keep_going
static mbc_nodal_t * mbc
#define MBC_R_R(mbc)
Definition: mbc.h:285
int getopt(int argc, char *const argv[], const char *opts)
Definition: getopt.c:93
int mbc_unix_init(mbc_t *mbc, const char *path)
Initialize communication using "unix" socket.
#define MBC_R_F(mbc)
Definition: mbc.h:292
int sleeptime
static mbc_nodal_t mbcx
static unsigned done
Definition: gust.cc:209
static unsigned steps
int mbc_inet_init(mbc_t *mbc, const char *host, short unsigned port)
Initialize communication using "inet" socket.
int mbc_modal_get_motion(mbc_modal_t *mbc)
Get modal motion from peer.
#define MBC_R_X(mbc)
Definition: mbc.h:283
char * optarg
Definition: getopt.c:74
#define MBC_R_EULER_123(mbc)
Definition: mbc.h:286
unsigned short int port
Definition: autopilot.c:143
void usage(void)
#define MBC_R_THETA(mbc)
Definition: mbc.h:284
static void sh(int signum)
mbc_t mbc
Definition: mbc.h:510
static int refnode
const char * path
Definition: autopilot.c:141
int mbc_modal_put_forces(mbc_modal_t *mbc, int last)
Put forces to peer.