Commit b31bfbb9fabbc2606d5f02af63923b77f3aa438d

Authored by Arnaud Blanchard
1 parent 1b3fd663

Adapt to new blc_program

Graph n blc_channels
@@ -6,7 +6,7 @@ project(o_gnuplot) @@ -6,7 +6,7 @@ project(o_gnuplot)
6 find_package(blc_channel REQUIRED) 6 find_package(blc_channel REQUIRED)
7 find_package(blc_program REQUIRED) 7 find_package(blc_program REQUIRED)
8 8
9 -add_definitions(${BL_DEFINITIONS}) 9 +add_definitions(${BL_DEFINITIONS} -std=c++14)
10 include_directories(${BL_INCLUDE_DIRS}) 10 include_directories(${BL_INCLUDE_DIRS})
11 add_executable(o_gnuplot src/o_gnuplot.cpp src/history_graph.cpp src/graph.cpp ) 11 add_executable(o_gnuplot src/o_gnuplot.cpp src/history_graph.cpp src/graph.cpp )
12 target_link_libraries(o_gnuplot ${BL_LIBRARIES}) 12 target_link_libraries(o_gnuplot ${BL_LIBRARIES})
@@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
4 #include <sys/time.h> 4 #include <sys/time.h>
5 #include <unistd.h> 5 #include <unistd.h>
6 6
  7 +using namespace std;
  8 +
7 void init_term(FILE *pipef, char const *title, char const* verbatim){ 9 void init_term(FILE *pipef, char const *title, char const* verbatim){
8 fprintf(pipef, "set term qt 1 noraise\n"); //Keep focus on the calling terminal 10 fprintf(pipef, "set term qt 1 noraise\n"); //Keep focus on the calling terminal
9 fprintf(pipef, "set datafile nofpe_trap\n"); //Speend up acquisition but crash if there is a problem with the DATA 11 fprintf(pipef, "set datafile nofpe_trap\n"); //Speend up acquisition but crash if there is a problem with the DATA
@@ -19,16 +21,21 @@ void init_term(FILE *pipef, char const *title, char const* verbatim){ @@ -19,16 +21,21 @@ void init_term(FILE *pipef, char const *title, char const* verbatim){
19 if (verbatim) fprintf(pipef, "%s\n", verbatim); 21 if (verbatim) fprintf(pipef, "%s\n", verbatim);
20 } 22 }
21 23
22 -void create_graph(blc_channel *input, char const *title, int refresh_period, float min, float max, float xmin, float xmax, float label_max, char const *verbatim){ 24 +void create_graph(deque <blc_channel>inputs, const char *title, int refresh_period, float ymin, float ymax, float xmin, float xmax, float label_max, char const *verbatim){
  25 + blc_channel *input=nullptr;
23 char const *gnuplot_format=NULL; 26 char const *gnuplot_format=NULL;
24 char command[LINE_MAX]; 27 char command[LINE_MAX];
25 - char code;  
26 - int i, offset, columns_nb=0, rows_nb=0; 28 + // char code;
  29 + int i, offset=0, columns_nb=0, rows_nb=0;
27 FILE *pipef; 30 FILE *pipef;
28 size_t element_size; 31 size_t element_size;
29 - char *buffer; 32 + int ret;
  33 + // char *buffer;
  34 +
  35 +
  36 + SYSTEM_ERROR_CHECK(pipef=popen("gnuplot", "w"), nullptr, "Calling gnuplot");
30 37
31 - SYSTEM_ERROR_CHECK(pipef=popen("gnuplot", "w"), NULL, "Calling gnuplot"); 38 + input=&inputs.front();
32 39
33 switch (input->dims_nb){ 40 switch (input->dims_nb){
34 case 0: 41 case 0:
@@ -36,15 +43,15 @@ void create_graph(blc_channel *input, char const *title, int refresh_period, flo @@ -36,15 +43,15 @@ void create_graph(blc_channel *input, char const *title, int refresh_period, flo
36 rows_nb=1; 43 rows_nb=1;
37 break; 44 break;
38 case 1: 45 case 1:
39 - columns_nb=input->dims[0].length; 46 + columns_nb=inputs[0].dims[0].length;
40 rows_nb=1; 47 rows_nb=1;
41 break; 48 break;
42 case 2: 49 case 2:
43 - columns_nb=input->dims[0].length;  
44 - rows_nb=input->dims[1].length; 50 + columns_nb=inputs[0].dims[0].length;
  51 + rows_nb=inputs[0].dims[1].length;
45 break; 52 break;
46 default: 53 default:
47 - EXIT_ON_ARRAY_ERROR(input, "Too many dims"); 54 + EXIT_ON_ARRAY_ERROR(&inputs[0], "Too many dims");
48 break; 55 break;
49 } 56 }
50 57
@@ -57,48 +64,73 @@ void create_graph(blc_channel *input, char const *title, int refresh_period, flo @@ -57,48 +64,73 @@ void create_graph(blc_channel *input, char const *title, int refresh_period, flo
57 gnuplot_format="%char"; 64 gnuplot_format="%char";
58 element_size=sizeof(char); 65 element_size=sizeof(char);
59 break; 66 break;
  67 + case 'UI16':
  68 + gnuplot_format="%uint16";
  69 + element_size=sizeof(uint16_t);
  70 + break;
  71 + case 'IN16':
  72 + gnuplot_format="%int16";
  73 + element_size=sizeof(int16_t);
  74 + break;
  75 + case 'UI32':
  76 + gnuplot_format="%uint32";
  77 + element_size=sizeof(uint32_t);
  78 + break;
  79 + case 'IN32':
  80 + gnuplot_format="%int32";
  81 + element_size=sizeof(int32_t);
  82 + break;
60 case 'FL32': 83 case 'FL32':
61 - gnuplot_format="%float"; 84 + gnuplot_format="%float32";
62 element_size=sizeof(float); 85 element_size=sizeof(float);
63 break; 86 break;
64 - default: EXIT_ON_ARRAY_ERROR(input, "The type is not managed"); 87 + case 'FL64':
  88 + gnuplot_format="%float64";
  89 + element_size=sizeof(double);
  90 + break;
  91 + default: EXIT_ON_ARRAY_ERROR(&inputs[0], "The type is not managed");
65 } 92 }
66 93
67 init_term(pipef, title, verbatim); 94 init_term(pipef, title, verbatim);
68 95
69 - if (min!=max) fprintf(pipef, "set yrange [%f:%f]\n", min, max); 96 + if (ymin!=ymax) fprintf(pipef, "set yrange [%f:%f]\n", ymin, ymax);
70 if (columns_nb==1) xmin=-1; 97 if (columns_nb==1) xmin=-1;
71 if (xmin!=xmax) fprintf(pipef, "set xrange [%f:%f]\n", xmin, xmax); 98 if (xmin!=xmax) fprintf(pipef, "set xrange [%f:%f]\n", xmin, xmax);
72 99
73 if (input->dims_nb==2){ 100 if (input->dims_nb==2){
74 fprintf(pipef, "set xrange [%f:%f]\n", 0.f, 10.f); 101 fprintf(pipef, "set xrange [%f:%f]\n", 0.f, 10.f);
75 fprintf(pipef, "set yrange [%f:%f]\n", 0.f, 10.f); 102 fprintf(pipef, "set yrange [%f:%f]\n", 0.f, 10.f);
76 - fprintf(pipef, "set zrange [%f:%f]\n", min, max); 103 + fprintf(pipef, "set zrange [%f:%f]\n", ymin, ymax);
77 fprintf(pipef, "set view 30,190\n"); 104 fprintf(pipef, "set view 30,190\n");
78 offset=snprintf(command, LINE_MAX, "splot '-' binary format='%s' array=%dx%d title 'values' with pm3d ", gnuplot_format, columns_nb, rows_nb); 105 offset=snprintf(command, LINE_MAX, "splot '-' binary format='%s' array=%dx%d title 'values' with pm3d ", gnuplot_format, columns_nb, rows_nb);
79 } 106 }
80 else{ 107 else{
81 - offset=snprintf(command, LINE_MAX, "plot '-' binary format='%s' record=%d using ($0*%f):1 title '%d' with %s", gnuplot_format, columns_nb, label_max/(float)columns_nb, 0, with_option);  
82 -  
83 - for(i=1; i!=rows_nb; i++){ 108 + offset=snprintf(command, LINE_MAX, "plot '-' binary format='%s' record=%d using ($0*%f):1 title '%s' with %s", gnuplot_format, columns_nb, label_max/(float)columns_nb, input->name+1, with_option);
  109 +
  110 + for(i=1; i<inputs.size();i++){
  111 + offset+=snprintf(command+offset, LINE_MAX-offset, ", '-' binary format='%s' record=%d using ($0*%f):1 title '%s' with %s", gnuplot_format, columns_nb, label_max/(float)columns_nb, inputs[i].name+1, with_option);
  112 + }
  113 + /* for(i=1; i!=rows_nb; i++){
84 if (i<10) code=48+i; 114 if (i<10) code=48+i;
85 else code=97+i-10; 115 else code=97+i-10;
86 offset+=snprintf(command+offset, LINE_MAX-offset, ", '-' binary format='%s' record=%d title '%c' with %s", gnuplot_format, columns_nb, code, with_option); 116 offset+=snprintf(command+offset, LINE_MAX-offset, ", '-' binary format='%s' record=%d title '%c' with %s", gnuplot_format, columns_nb, code, with_option);
87 - } 117 + }*/
88 } 118 }
89 119
90 - buffer=MANY_ALLOCATIONS(input->size, char);  
91 -  
92 - blc_loop_try_add_waiting_semaphore(input->sem_new_data); 120 + // sleep(3);
  121 + for (i=0;i<inputs.size();i++) {
  122 + blc_loop_try_add_waiting_semaphore(inputs[i].sem_new_data);
  123 + blc_loop_try_add_posting_semaphore(inputs[i].sem_ack_data);
  124 + }
93 BLC_COMMAND_LOOP(refresh_period){ 125 BLC_COMMAND_LOOP(refresh_period){
94 - memcpy(buffer, input->data, input->size);  
95 - if (input->sem_ack_data) SYSTEM_ERROR_CHECK(sem_post(input->sem_ack_data), -1, NULL);  
96 fprintf(pipef, "\n%s\n", command); 126 fprintf(pipef, "\n%s\n", command);
97 - SYSTEM_ERROR_CHECK(fwrite(buffer, element_size, columns_nb*rows_nb, pipef), -1, NULL);  
98 - SYSTEM_ERROR_CHECK(fflush(pipef), -1, NULL); 127 + for (i=0;i<inputs.size();i++) {
  128 + SYSTEM_SUCCESS_CHECK(fwrite(inputs[i].data, element_size, columns_nb, pipef), columns_nb, NULL);
  129 + }
  130 + SYSTEM_SUCCESS_CHECK(fflush(pipef), 0, nullptr);
99 } 131 }
100 - SYSTEM_ERROR_CHECK(fclose(pipef), -1, NULL);  
101 - FREE(buffer); 132 + SYSTEM_ERROR_CHECK(ret=pclose(pipef), -1, NULL);
  133 + if (ret!=0) EXIT_ON_ERROR("Gnuplot quititing with error code '%d'", ret);
102 } 134 }
103 135
104 136
@@ -10,10 +10,13 @@ @@ -10,10 +10,13 @@
10 #define GRAPH_H 10 #define GRAPH_H
11 #include "blc_channel.h" 11 #include "blc_channel.h"
12 12
  13 +#include <deque>
  14 +
  15 +
13 extern char const *with_option, *style_option; 16 extern char const *with_option, *style_option;
14 17
15 void init_term(FILE *pipef, char const *title, char const* verbatim); 18 void init_term(FILE *pipef, char const *title, char const* verbatim);
16 -void create_history_graph(blc_channel *input, char const *title, int history_length, int refresh_period, int sampling_period, float min, float max, char const *verbatim);  
17 -void create_graph(blc_channel *input, char const *title, int refresh_period, float min, float max, float xmin, float xmax, float label_max, char const *verbatim); 19 +void create_history_graph(std::deque <blc_channel> inputs, char const *title, int history_length, int refresh_period, int sampling_period, float min, float max, char const *verbatim);
  20 +void create_graph(std::deque <blc_channel> inputs, char const*title, int refresh_period, float min, float max, float xmin, float xmax, float label_max, char const *verbatim);
18 21
19 #endif /* history_graph_h */ 22 #endif /* history_graph_h */
@@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
4 #include <sys/time.h> 4 #include <sys/time.h>
5 #include <unistd.h> 5 #include <unistd.h>
6 6
  7 +using namespace std;
  8 +
7 typedef struct history:blc_array{ 9 typedef struct history:blc_array{
8 blc_channel *input; 10 blc_channel *input;
9 11
@@ -99,15 +101,20 @@ static void *refresh_history_cb(void *history_pt){ @@ -99,15 +101,20 @@ static void *refresh_history_cb(void *history_pt){
99 return NULL; 101 return NULL;
100 } 102 }
101 103
102 -void create_history_graph(blc_channel *input, char const *title, int history_length, int refresh_period, int sampling_period, float min, float max, char const *verbatim){  
103 - char const *gnuplot_format=NULL; 104 +void create_history_graph(deque <blc_channel> inputs, char const *title, int history_length, int refresh_period, int sampling_period, float min, float max, char const *verbatim){
  105 +
  106 + blc_channel *input=nullptr;
  107 + char const *gnuplot_format=NULL;
104 char command[LINE_MAX]; 108 char command[LINE_MAX];
105 109
106 char code; 110 char code;
107 int i, offset, columns_nb=0; 111 int i, offset, columns_nb=0;
108 FILE *pipef; 112 FILE *pipef;
109 pthread_t thread; 113 pthread_t thread;
110 - 114 +
  115 + if (inputs.size()>1) EXIT_ON_ERROR("Only one channel is managed for history plots");
  116 + else input=&inputs.back();
  117 +
111 switch (input->dims_nb){ 118 switch (input->dims_nb){
112 case 0: 119 case 0:
113 columns_nb=1; 120 columns_nb=1;
@@ -5,8 +5,11 @@ @@ -5,8 +5,11 @@
5 #include <pthread.h> 5 #include <pthread.h>
6 #include <sys/time.h> 6 #include <sys/time.h>
7 #include "graph.h" 7 #include "graph.h"
  8 +#include <deque> //We use deque instread of vector to warantly address of objects
8 9
9 -blc_channel input; 10 +using namespace std;
  11 +
  12 +deque <blc_channel> inputs;
10 blc_array history_array; 13 blc_array history_array;
11 14
12 char const *with_option, *style_option; 15 char const *with_option, *style_option;
@@ -18,23 +21,26 @@ int final_columns_nb, final_rows_nb; @@ -18,23 +21,26 @@ int final_columns_nb, final_rows_nb;
18 int offset=0; 21 int offset=0;
19 int bands=1; 22 int bands=1;
20 int dims_nb, *lengths; 23 int dims_nb, *lengths;
21 -double min, max; 24 +double ymin, ymax;
22 enum {RUN, PAUSE}; 25 enum {RUN, PAUSE};
23 int status=RUN; 26 int status=RUN;
24 27
25 -void refresh_period_cb(char const*argument, void*){ 28 +void refresh_period_cb(char *argument, void*){
26 sampling_period=strtol(argument, NULL, 10)*1000; 29 sampling_period=strtol(argument, NULL, 10)*1000;
27 } 30 }
28 31
29 int main(int argc, char *argv[]){ 32 int main(int argc, char *argv[]){
30 - char const *refresh_string, *min_str, *max_str, *history_str, *channel_name, *sample_string, *verbatim; 33 + char const *refresh_string, *ymin_str, *ymax_str, *history_str, *sample_string, *verbatim;
  34 + char **channel_names;
31 char const *xmin_str, *xmax_str, *label_max_str; 35 char const *xmin_str, *xmax_str, *label_max_str;
32 float xmin, xmax, lmax; 36 float xmin, xmax, lmax;
33 - int status=0; 37 + int status=0, total_length;
  38 + uint32_t type;
  39 + int dims_nb;
34 40
35 blc_program_set_description("Display the content of the blc_channel depending on its type and format"); 41 blc_program_set_description("Display the content of the blc_channel depending on its type and format");
36 - blc_program_add_option(&min_str, 'm', "min", "FL32", "minimal value", NULL);  
37 - blc_program_add_option(&max_str, 'M', "max", "FL32", "maximal value", NULL); 42 + blc_program_add_option(&ymin_str, 'm', "min", "FL32", "minimal value", NULL);
  43 + blc_program_add_option(&ymax_str, 'M', "max", "FL32", "maximal value", NULL);
38 blc_program_add_option(&sample_string, 'p', "period", "UI32", "sampling period in ms or history", "10"); 44 blc_program_add_option(&sample_string, 'p', "period", "UI32", "sampling period in ms or history", "10");
39 blc_program_add_option(&style_option, 's', "style", "string", "gnuplot option set option (style, boxwidth, ...)", "fill solid"); 45 blc_program_add_option(&style_option, 's', "style", "string", "gnuplot option set option (style, boxwidth, ...)", "fill solid");
40 blc_program_add_option(&verbatim, 't', "text", "string", "text directly put on the gnuplot set commandline", NULL); 46 blc_program_add_option(&verbatim, 't', "text", "string", "text directly put on the gnuplot set commandline", NULL);
@@ -44,49 +50,62 @@ int main(int argc, char *argv[]){ @@ -44,49 +50,62 @@ int main(int argc, char *argv[]){
44 blc_program_add_option(&label_max_str, 'L', "label-max", "FL32", "display the absisca scale in order to have the last value as label-max ", NULL); 50 blc_program_add_option(&label_max_str, 'L', "label-max", "FL32", "display the absisca scale in order to have the last value as label-max ", NULL);
45 blc_program_add_option(&history_str, 'H', "history", "UI32", "size of the history", NULL); 51 blc_program_add_option(&history_str, 'H', "history", "UI32", "size of the history", NULL);
46 blc_program_add_option(&refresh_string, 'P', "period", "UI32", "graph refresh period in ms", "100"); 52 blc_program_add_option(&refresh_string, 'P', "period", "UI32", "graph refresh period in ms", "100");
47 - blc_program_add_parameter(&channel_name, "blc_channel", 1, "channel you want to graph", NULL);  
48 - 53 + blc_program_add_multiple_parameters(&channel_names, "blc_channel", -1, "channel you want to graph");
  54 +
49 blc_program_init(&argc, &argv, blc_quit); 55 blc_program_init(&argc, &argv, blc_quit);
50 blc_command_forward_blc_channels(); 56 blc_command_forward_blc_channels();
51 57
52 - input.open(channel_name, BLC_CHANNEL_READ);  
53 - if (min_str) min=strtof(min_str, NULL);  
54 - else switch (input.type){  
55 - case 'UIN8':case 'UI16':case 'UI32':case 'IN16':case 'IN32':case 'IN64':case 'FL32':case'FL64':min=0.0;break;  
56 - case 'INT8':min=INT8_MIN;break;  
57 - default: EXIT_ON_CHANNEL_ERROR(&input, "No default min value"); 58 + for (char *const*channel_name_pt = channel_names; *channel_name_pt!=nullptr; channel_name_pt++){
  59 + inputs.emplace_back(*channel_name_pt, BLC_CHANNEL_READ);
  60 + if (inputs.size()==1){ //First time
  61 + type=inputs.back().type;
  62 + dims_nb=inputs.back().dims_nb;
  63 + total_length=inputs.back().total_length;
  64 + }
  65 + else{
  66 + if (type!=inputs.back().type) EXIT_ON_ERROR("Type of different channels must be the same");
  67 + if (total_length!=inputs.back().total_length) EXIT_ON_ERROR("Total_leength of different channels must be the same");
  68 + if (dims_nb!=inputs.back().dims_nb) EXIT_ON_ERROR("Number of dims of different channels must be the same");
  69 + }
  70 + }
  71 +
  72 + if (ymin_str) ymin=strtof(ymin_str, NULL);
  73 + else switch (type){
  74 + case 'UIN8':case 'UI16':case 'UI32':case 'IN16':case 'IN32':case 'IN64':case 'FL32':case'FL64':ymin=0.0;break;
  75 + case 'INT8':ymin=INT8_MIN;break;
  76 + default: EXIT_ON_ERROR( "No default min value for type");
58 } 77 }
59 78
60 - if (max_str) max=strtof(max_str, NULL);  
61 - else switch (input.type){  
62 - case 'UIN8':max=UINT8_MAX;break;  
63 - case 'INT8':max=INT8_MAX;break;  
64 - case 'FL32': case 'FL64':max=1.0;break;  
65 - default: EXIT_ON_CHANNEL_ERROR(&input, "No default max value"); 79 + if (ymax_str) ymax=strtof(ymax_str, NULL);
  80 + else switch (type){
  81 + case 'UIN8':ymax=UINT8_MAX;break;
  82 + case 'INT8':ymax=INT8_MAX;break;
  83 + case 'FL32': case 'FL64':ymax=1.0;break;
  84 + default: EXIT_ON_ERROR( "No default max value for type");
66 } 85 }
67 86
68 if (xmin_str) SSCANF(1, xmin_str, "%f", &xmin); 87 if (xmin_str) SSCANF(1, xmin_str, "%f", &xmin);
69 else xmin=0; 88 else xmin=0;
70 89
71 if (xmax_str) SSCANF(1, xmax_str, "%f", &xmax); 90 if (xmax_str) SSCANF(1, xmax_str, "%f", &xmax);
72 - else xmax=input.total_length; 91 + else xmax=total_length;
73 92
74 if (label_max_str) { 93 if (label_max_str) {
75 SSCANF(1, label_max_str, "%f", &lmax); 94 SSCANF(1, label_max_str, "%f", &lmax);
76 if (xmax_str==NULL) xmax=lmax; //We still want to see all the graph 95 if (xmax_str==NULL) xmax=lmax; //We still want to see all the graph
77 } 96 }
78 - else lmax=input.total_length; 97 + else lmax=total_length;
79 98
80 sampling_period=strtol(refresh_string, NULL, 10)*1000; 99 sampling_period=strtol(refresh_string, NULL, 10)*1000;
81 100
82 fprintf(stderr, "=== %s: ", blc_program_name); 101 fprintf(stderr, "=== %s: ", blc_program_name);
83 if (history_str) fprintf(stderr, "sample period (%.3fms), history(%s), ", sampling_period/1000.f, history_str); 102 if (history_str) fprintf(stderr, "sample period (%.3fms), history(%s), ", sampling_period/1000.f, history_str);
84 - fprintf(stderr, "min(%.3lf), max(%.2lf) === \n", min, max); 103 + fprintf(stderr, "min(%.3lf), max(%.2lf) === \n", ymin, ymax);
85 104
86 blc_command_add("p", refresh_period_cb, "ms", "sampling period", NULL); 105 blc_command_add("p", refresh_period_cb, "ms", "sampling period", NULL);
87 106
88 - if (history_str) create_history_graph(&input, input.name+1, strtol(history_str, NULL, 10), sampling_period, strtol(sample_string, NULL, 10)*1000, min, max, verbatim);  
89 - else create_graph(&input, input.name+1, sampling_period, min, max, xmin, xmax, lmax, verbatim); 107 + if (history_str) create_history_graph(inputs, (char const*)inputs[0].name+1, strtol(history_str, NULL, 10), sampling_period, strtol(sample_string, NULL, 10)*1000, ymin, ymax, verbatim);
  108 + else create_graph(inputs, inputs[0].name+1, sampling_period, ymin, ymax, xmin, xmax, lmax, verbatim);
90 109
91 return (status); 110 return (status);
92 } 111 }
@@ -20,7 +20,7 @@ double min, max; @@ -20,7 +20,7 @@ double min, max;
20 enum {RUN, PAUSE}; 20 enum {RUN, PAUSE};
21 int status=RUN; 21 int status=RUN;
22 22
23 -void refresh_period_cb(char const*argument, void*){ 23 +void refresh_period_cb(char *argument, void*){
24 sampling_period=strtol(argument, NULL, 10)*1000; 24 sampling_period=strtol(argument, NULL, 10)*1000;
25 } 25 }
26 26