]> rtime.felk.cvut.cz Git - eurobot/public.git/blob - src/camera/barcam/c2gnuplot.h
Merge branch 'maint-demo'
[eurobot/public.git] / src / camera / barcam / c2gnuplot.h
1 /*
2  * c2gnuplot.h
3  *
4  * Copyright 2007       Zoltan Kuscsik <kuscsik@gmail.com>
5  *
6  * This file is GPLv2 as found in COPYING.
7  */
8
9                 
10 /*
11   @fille         c2gnuplo.h
12   @author       Z. Kuscsik
13   @date         jan 2007
14   @version      $Revision: 0.2 $
15   @brief        C interface to gnuplot.
16
17   gnuplot is a freely available, command-driven graphical display tool for
18   Unix. It compiles and works quite well on a number of Unix flavours as
19   well as other operating systems. The following module enables sending
20   display requests to gnuplot through simple C calls.
21   This code is partially based on the gnuplot_i.h library:
22         http://ndevilla.free.fr/gnuplot/
23   
24 --------------------------------------------------------------------------*/
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <sys/stat.h>
29 #include <string>
30 #include <stdarg.h>
31 #include <map>
32 //#include "operations.h"
33
34 using namespace std;
35
36 #define GNPL_COMM_SIZE 2000
37 #define MAX_COMM_NAME_LENGTH 100
38 #define MAX_PATH_NAME_LENGTH 1000
39 #define tmp_name "/tmp/tmpdataXXXXXXX"
40 unsigned int FIRST_INIT = 1;
41
42 char command_list[][MAX_COMM_NAME_LENGTH] = {"gnuplot","ppmto4ym","mpeg2enc"};
43
44 #define NUMBER_OF_EXTERNAL_COMMANDS  (sizeof command_list)/MAX_COMM_NAME_LENGTH     //number of external commands
45
46 map<char,char> path_list;
47
48
49
50
51 class gnuplot_window{
52                 public:
53                         gnuplot_window();
54                         void splot_data();      //plot 3d data file
55                         void splot_data(char *  cmd, ...);
56                         void plot_data();       //plot 2d data file
57                         void plot_data(char *  cmd, ...);
58                         void flush();                   //flush gnuplot data
59                         void data(char *  cmd, ...);    //write data to gnuplot session
60                         void command(char *  cmd, ...); //set gnuplot variables and draw functions
61                         void mpeg_out(char * cmd, ...);
62                         char* fit_range;
63                         char* fit_function;
64                         void fit(char * cmd, ...);
65                         float get_variable(char * cmd, ...);
66                 private:
67                         FILE *pipe;
68                         FILE *input_param;
69                         FILE *input;
70                         char gnuplot_fifo[(sizeof tmp_name)];
71                         char gnuplot_output_fifo[(sizeof tmp_name)];
72         };
73
74
75
76 char  * get_program_path(char * pname)
77 {
78     int         i, j, lg;
79     char    *   path;
80     static char buf[MAX_PATH_NAME_LENGTH];
81
82     /* Trivial case: try in CWD */
83     sprintf(buf, "./%s", pname) ;
84     if (access(buf, X_OK)==0) {
85         sprintf(buf, ".");
86         return buf ;
87     }
88     /* Try out in all paths given in the PATH variable */
89     buf[0] = 0;
90     path = getenv("PATH") ;
91     if (path!=NULL) {
92         for (i=0; path[i]; ) {
93             for (j=i ; (path[j]) && (path[j]!=':') ; j++);
94             lg = j - i;
95             strncpy(buf, path + i, lg);
96             if (lg == 0) buf[lg++] = '.';
97             buf[lg++] = '/';
98             strcpy(buf + lg, pname);
99             if (access(buf, X_OK) == 0) {
100                 /* Found it! */
101                 break ;
102             }
103             buf[0] = 0;
104             i = j;
105             if (path[i] == ':') i++ ;
106         }
107     } else {
108                 fprintf(stderr, "PATH variable not set\n");
109         }
110     /* If the buffer is still empty, the command was not found */
111     if (buf[0] == 0) return NULL ;
112     /* Otherwise truncate the command name to yield path only */
113     lg = strlen(buf) - 1 ;
114     while (buf[lg]!='/') {
115         buf[lg]=0 ;
116         lg -- ;
117     }
118     buf[lg] = 0;
119     return buf ;
120 }
121
122
123
124 void gnuplot_window::mpeg_out(char * cmd, ...)
125 {
126     va_list ap ;
127     char    local_cmd[GNPL_COMM_SIZE];
128
129     va_start(ap, cmd);
130     vsprintf(local_cmd, cmd, ap);
131     va_end(ap);
132     strcat(local_cmd, "\n");
133     command("set term pbm color ");
134     command("set output '| ppmtoy4m  -S 420mpeg2 | mpeg2enc -o %s",local_cmd);
135     fit_range="[*:*]";
136     fit_function="";
137
138 }
139
140 void gnuplot_window::data(char *  cmd, ...)
141 {
142
143     va_list ap ;
144     char    local_cmd[GNPL_COMM_SIZE];
145
146    if(FIRST_INIT)
147                 {
148                 FIRST_INIT=0;
149                 }
150
151     va_start(ap, cmd);
152     vsprintf(local_cmd, cmd, ap);
153     va_end(ap);
154
155     strcat(local_cmd, "\n");
156     fputs(local_cmd, input);
157     fflush(input);
158 }
159
160
161 void gnuplot_window::command(char *  cmd, ...)
162 {
163     va_list ap ;
164     char    local_cmd[GNPL_COMM_SIZE];
165
166     va_start(ap, cmd);
167     vsprintf(local_cmd, cmd, ap);
168     va_end(ap);
169      
170     strcat(local_cmd, "\n");
171     
172 fprintf(pipe,local_cmd);
173 fflush(pipe);
174 }
175
176 void gnuplot_window::plot_data()
177 {
178 fprintf(pipe,"plot  '%s'\n",gnuplot_fifo);
179 fflush(pipe);
180 input = fopen(gnuplot_fifo,"w");
181 }
182
183 void gnuplot_window::splot_data()
184 {
185 fprintf(pipe,"splot  '%s'\n",gnuplot_fifo);
186 fflush(pipe);
187 input = fopen(gnuplot_fifo,"w");
188 }
189
190 void gnuplot_window::splot_data(char *  cmd, ...)
191 {
192     va_list ap ;
193     char    local_cmd[GNPL_COMM_SIZE];
194
195     va_start(ap, cmd);
196     vsprintf(local_cmd, cmd, ap);
197     va_end(ap);
198
199     strcat(local_cmd, "\n");
200     
201     
202 fprintf(pipe,"splot  '%s' %s\n",gnuplot_fifo,local_cmd);
203 fflush(pipe);
204 input = fopen(gnuplot_fifo,"w");
205 }
206 void gnuplot_window::plot_data(char *  cmd, ...)
207 {
208     va_list ap ;
209     char    local_cmd[GNPL_COMM_SIZE];
210
211     va_start(ap, cmd);
212     vsprintf(local_cmd, cmd, ap);
213     va_end(ap);
214
215     strcat(local_cmd, "\n");
216     
217     
218 fprintf(pipe,"plot  '%s' %s\n",gnuplot_fifo,local_cmd);
219 fflush(pipe);
220 input = fopen(gnuplot_fifo,"w");
221 }
222
223 /*
224  *      Fit function
225  *
226  */
227
228 void gnuplot_window::fit(char *  cmd, ...)
229 {
230     va_list ap ;
231     char    local_cmd[GNPL_COMM_SIZE];
232     va_start(ap, cmd);
233     vsprintf(local_cmd, cmd, ap);
234     va_end(ap);
235
236     strcat(local_cmd, "\n");
237
238    if(fit_function=="")
239         fprintf(stderr,"Function for datafit is not defined. Please define the fit_function parameter\n");
240
241     fprintf(pipe,"fit [%s] %s  '%s' %s\n",fit_range, fit_function,gnuplot_fifo,local_cmd);
242    fflush(pipe);
243     input = fopen(gnuplot_fifo,"w");
244
245
246         
247
248 }
249
250 void gnuplot_window::flush()
251 {
252 fclose(input);
253 fflush(pipe);
254 }
255
256
257 gnuplot_window::gnuplot_window()
258 {
259  int fd;
260  pipe=popen("/usr/bin/gnuplot  2>/dev/null","w");
261  setvbuf(pipe, NULL, _IONBF, 0 );
262
263  strcpy(gnuplot_fifo,tmp_name);
264  strcpy(gnuplot_output_fifo,tmp_name);
265  if((fd=mkstemp(gnuplot_fifo) ) < 0) { fprintf(stderr,"Creating temporary filename failed\n"); exit(0);}
266          close(fd); remove(gnuplot_fifo);
267
268  if (mkfifo(gnuplot_fifo, S_IRUSR | S_IWUSR ) != 0) {fprintf(stderr,"Make fifo file %s failed\n",gnuplot_fifo); exit(0);}
269
270
271  if((fd=mkstemp(gnuplot_output_fifo) ) < 0) { fprintf(stderr,"Creating temporary filename failed\n"); exit(0);}
272          close(fd); remove(gnuplot_output_fifo);
273
274  if (mkfifo(gnuplot_output_fifo, S_IRUSR | S_IWUSR ) != 0) {fprintf(stderr,"Make fifo file %s failed\n",gnuplot_output_fifo); exit(0);}
275         
276  fflush(pipe); 
277  command("set fit logfile '/dev/null'");
278
279 }
280
281 float gnuplot_window::get_variable(char *  cmd, ...)
282 {
283     va_list ap ;
284     char    local_cmd[GNPL_COMM_SIZE];
285     va_start(ap, cmd);
286     vsprintf(local_cmd, cmd, ap);
287     va_end(ap);
288
289         float param;
290         command("set print '%s'",gnuplot_output_fifo);
291
292         command("print %s",local_cmd);
293
294         usleep(10000); /* There must be a little sleep because of asynchronous relation to the gnuplot pipe*/
295
296         input_param=fopen(gnuplot_output_fifo,"r");
297
298         fscanf(input_param,"%f",&param);
299
300         fclose(input_param);
301
302         return param;
303 }
304