Commit b31bfbb9 authored by Arnaud Blanchard's avatar Arnaud Blanchard
Browse files

Adapt to new blc_program

Graph n blc_channels
parent 1b3fd663
......@@ -6,7 +6,7 @@ project(o_gnuplot)
find_package(blc_channel REQUIRED)
find_package(blc_program REQUIRED)
add_definitions(${BL_DEFINITIONS})
add_definitions(${BL_DEFINITIONS} -std=c++14)
include_directories(${BL_INCLUDE_DIRS})
add_executable(o_gnuplot src/o_gnuplot.cpp src/history_graph.cpp src/graph.cpp )
target_link_libraries(o_gnuplot ${BL_LIBRARIES})
......
......@@ -4,6 +4,8 @@
#include <sys/time.h>
#include <unistd.h>
using namespace std;
void init_term(FILE *pipef, char const *title, char const* verbatim){
fprintf(pipef, "set term qt 1 noraise\n"); //Keep focus on the calling terminal
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){
if (verbatim) fprintf(pipef, "%s\n", verbatim);
}
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){
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){
blc_channel *input=nullptr;
char const *gnuplot_format=NULL;
char command[LINE_MAX];
char code;
int i, offset, columns_nb=0, rows_nb=0;
// char code;
int i, offset=0, columns_nb=0, rows_nb=0;
FILE *pipef;
size_t element_size;
char *buffer;
int ret;
// char *buffer;
SYSTEM_ERROR_CHECK(pipef=popen("gnuplot", "w"), nullptr, "Calling gnuplot");
SYSTEM_ERROR_CHECK(pipef=popen("gnuplot", "w"), NULL, "Calling gnuplot");
input=&inputs.front();
switch (input->dims_nb){
case 0:
......@@ -36,15 +43,15 @@ void create_graph(blc_channel *input, char const *title, int refresh_period, flo
rows_nb=1;
break;
case 1:
columns_nb=input->dims[0].length;
columns_nb=inputs[0].dims[0].length;
rows_nb=1;
break;
case 2:
columns_nb=input->dims[0].length;
rows_nb=input->dims[1].length;
columns_nb=inputs[0].dims[0].length;
rows_nb=inputs[0].dims[1].length;
break;
default:
EXIT_ON_ARRAY_ERROR(input, "Too many dims");
EXIT_ON_ARRAY_ERROR(&inputs[0], "Too many dims");
break;
}
......@@ -57,48 +64,73 @@ void create_graph(blc_channel *input, char const *title, int refresh_period, flo
gnuplot_format="%char";
element_size=sizeof(char);
break;
case 'UI16':
gnuplot_format="%uint16";
element_size=sizeof(uint16_t);
break;
case 'IN16':
gnuplot_format="%int16";
element_size=sizeof(int16_t);
break;
case 'UI32':
gnuplot_format="%uint32";
element_size=sizeof(uint32_t);
break;
case 'IN32':
gnuplot_format="%int32";
element_size=sizeof(int32_t);
break;
case 'FL32':
gnuplot_format="%float";
gnuplot_format="%float32";
element_size=sizeof(float);
break;
default: EXIT_ON_ARRAY_ERROR(input, "The type is not managed");
case 'FL64':
gnuplot_format="%float64";
element_size=sizeof(double);
break;
default: EXIT_ON_ARRAY_ERROR(&inputs[0], "The type is not managed");
}
init_term(pipef, title, verbatim);
if (min!=max) fprintf(pipef, "set yrange [%f:%f]\n", min, max);
if (ymin!=ymax) fprintf(pipef, "set yrange [%f:%f]\n", ymin, ymax);
if (columns_nb==1) xmin=-1;
if (xmin!=xmax) fprintf(pipef, "set xrange [%f:%f]\n", xmin, xmax);
if (input->dims_nb==2){
fprintf(pipef, "set xrange [%f:%f]\n", 0.f, 10.f);
fprintf(pipef, "set yrange [%f:%f]\n", 0.f, 10.f);
fprintf(pipef, "set zrange [%f:%f]\n", min, max);
fprintf(pipef, "set zrange [%f:%f]\n", ymin, ymax);
fprintf(pipef, "set view 30,190\n");
offset=snprintf(command, LINE_MAX, "splot '-' binary format='%s' array=%dx%d title 'values' with pm3d ", gnuplot_format, columns_nb, rows_nb);
}
else{
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);
for(i=1; i!=rows_nb; i++){
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);
for(i=1; i<inputs.size();i++){
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);
}
/* for(i=1; i!=rows_nb; i++){
if (i<10) code=48+i;
else code=97+i-10;
offset+=snprintf(command+offset, LINE_MAX-offset, ", '-' binary format='%s' record=%d title '%c' with %s", gnuplot_format, columns_nb, code, with_option);
}
}*/
}
buffer=MANY_ALLOCATIONS(input->size, char);
blc_loop_try_add_waiting_semaphore(input->sem_new_data);
// sleep(3);
for (i=0;i<inputs.size();i++) {
blc_loop_try_add_waiting_semaphore(inputs[i].sem_new_data);
blc_loop_try_add_posting_semaphore(inputs[i].sem_ack_data);
}
BLC_COMMAND_LOOP(refresh_period){
memcpy(buffer, input->data, input->size);
if (input->sem_ack_data) SYSTEM_ERROR_CHECK(sem_post(input->sem_ack_data), -1, NULL);
fprintf(pipef, "\n%s\n", command);
SYSTEM_ERROR_CHECK(fwrite(buffer, element_size, columns_nb*rows_nb, pipef), -1, NULL);
SYSTEM_ERROR_CHECK(fflush(pipef), -1, NULL);
for (i=0;i<inputs.size();i++) {
SYSTEM_SUCCESS_CHECK(fwrite(inputs[i].data, element_size, columns_nb, pipef), columns_nb, NULL);
}
SYSTEM_SUCCESS_CHECK(fflush(pipef), 0, nullptr);
}
SYSTEM_ERROR_CHECK(fclose(pipef), -1, NULL);
FREE(buffer);
SYSTEM_ERROR_CHECK(ret=pclose(pipef), -1, NULL);
if (ret!=0) EXIT_ON_ERROR("Gnuplot quititing with error code '%d'", ret);
}
......
......@@ -10,10 +10,13 @@
#define GRAPH_H
#include "blc_channel.h"
#include <deque>
extern char const *with_option, *style_option;
void init_term(FILE *pipef, char const *title, char const* verbatim);
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);
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);
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);
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);
#endif /* history_graph_h */
......@@ -4,6 +4,8 @@
#include <sys/time.h>
#include <unistd.h>
using namespace std;
typedef struct history:blc_array{
blc_channel *input;
......@@ -99,15 +101,20 @@ static void *refresh_history_cb(void *history_pt){
return NULL;
}
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){
char const *gnuplot_format=NULL;
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){
blc_channel *input=nullptr;
char const *gnuplot_format=NULL;
char command[LINE_MAX];
char code;
int i, offset, columns_nb=0;
FILE *pipef;
pthread_t thread;
if (inputs.size()>1) EXIT_ON_ERROR("Only one channel is managed for history plots");
else input=&inputs.back();
switch (input->dims_nb){
case 0:
columns_nb=1;
......
......@@ -5,8 +5,11 @@
#include <pthread.h>
#include <sys/time.h>
#include "graph.h"
#include <deque> //We use deque instread of vector to warantly address of objects
blc_channel input;
using namespace std;
deque <blc_channel> inputs;
blc_array history_array;
char const *with_option, *style_option;
......@@ -18,23 +21,26 @@ int final_columns_nb, final_rows_nb;
int offset=0;
int bands=1;
int dims_nb, *lengths;
double min, max;
double ymin, ymax;
enum {RUN, PAUSE};
int status=RUN;
void refresh_period_cb(char const*argument, void*){
void refresh_period_cb(char *argument, void*){
sampling_period=strtol(argument, NULL, 10)*1000;
}
int main(int argc, char *argv[]){
char const *refresh_string, *min_str, *max_str, *history_str, *channel_name, *sample_string, *verbatim;
char const *refresh_string, *ymin_str, *ymax_str, *history_str, *sample_string, *verbatim;
char **channel_names;
char const *xmin_str, *xmax_str, *label_max_str;
float xmin, xmax, lmax;
int status=0;
int status=0, total_length;
uint32_t type;
int dims_nb;
blc_program_set_description("Display the content of the blc_channel depending on its type and format");
blc_program_add_option(&min_str, 'm', "min", "FL32", "minimal value", NULL);
blc_program_add_option(&max_str, 'M', "max", "FL32", "maximal value", NULL);
blc_program_add_option(&ymin_str, 'm', "min", "FL32", "minimal value", NULL);
blc_program_add_option(&ymax_str, 'M', "max", "FL32", "maximal value", NULL);
blc_program_add_option(&sample_string, 'p', "period", "UI32", "sampling period in ms or history", "10");
blc_program_add_option(&style_option, 's', "style", "string", "gnuplot option set option (style, boxwidth, ...)", "fill solid");
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[]){
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);
blc_program_add_option(&history_str, 'H', "history", "UI32", "size of the history", NULL);
blc_program_add_option(&refresh_string, 'P', "period", "UI32", "graph refresh period in ms", "100");
blc_program_add_parameter(&channel_name, "blc_channel", 1, "channel you want to graph", NULL);
blc_program_add_multiple_parameters(&channel_names, "blc_channel", -1, "channel you want to graph");
blc_program_init(&argc, &argv, blc_quit);
blc_command_forward_blc_channels();
input.open(channel_name, BLC_CHANNEL_READ);
if (min_str) min=strtof(min_str, NULL);
else switch (input.type){
case 'UIN8':case 'UI16':case 'UI32':case 'IN16':case 'IN32':case 'IN64':case 'FL32':case'FL64':min=0.0;break;
case 'INT8':min=INT8_MIN;break;
default: EXIT_ON_CHANNEL_ERROR(&input, "No default min value");
for (char *const*channel_name_pt = channel_names; *channel_name_pt!=nullptr; channel_name_pt++){
inputs.emplace_back(*channel_name_pt, BLC_CHANNEL_READ);
if (inputs.size()==1){ //First time
type=inputs.back().type;
dims_nb=inputs.back().dims_nb;
total_length=inputs.back().total_length;
}
else{
if (type!=inputs.back().type) EXIT_ON_ERROR("Type of different channels must be the same");
if (total_length!=inputs.back().total_length) EXIT_ON_ERROR("Total_leength of different channels must be the same");
if (dims_nb!=inputs.back().dims_nb) EXIT_ON_ERROR("Number of dims of different channels must be the same");
}
}
if (ymin_str) ymin=strtof(ymin_str, NULL);
else switch (type){
case 'UIN8':case 'UI16':case 'UI32':case 'IN16':case 'IN32':case 'IN64':case 'FL32':case'FL64':ymin=0.0;break;
case 'INT8':ymin=INT8_MIN;break;
default: EXIT_ON_ERROR( "No default min value for type");
}
if (max_str) max=strtof(max_str, NULL);
else switch (input.type){
case 'UIN8':max=UINT8_MAX;break;
case 'INT8':max=INT8_MAX;break;
case 'FL32': case 'FL64':max=1.0;break;
default: EXIT_ON_CHANNEL_ERROR(&input, "No default max value");
if (ymax_str) ymax=strtof(ymax_str, NULL);
else switch (type){
case 'UIN8':ymax=UINT8_MAX;break;
case 'INT8':ymax=INT8_MAX;break;
case 'FL32': case 'FL64':ymax=1.0;break;
default: EXIT_ON_ERROR( "No default max value for type");
}
if (xmin_str) SSCANF(1, xmin_str, "%f", &xmin);
else xmin=0;
if (xmax_str) SSCANF(1, xmax_str, "%f", &xmax);
else xmax=input.total_length;
else xmax=total_length;
if (label_max_str) {
SSCANF(1, label_max_str, "%f", &lmax);
if (xmax_str==NULL) xmax=lmax; //We still want to see all the graph
}
else lmax=input.total_length;
else lmax=total_length;
sampling_period=strtol(refresh_string, NULL, 10)*1000;
fprintf(stderr, "=== %s: ", blc_program_name);
if (history_str) fprintf(stderr, "sample period (%.3fms), history(%s), ", sampling_period/1000.f, history_str);
fprintf(stderr, "min(%.3lf), max(%.2lf) === \n", min, max);
fprintf(stderr, "min(%.3lf), max(%.2lf) === \n", ymin, ymax);
blc_command_add("p", refresh_period_cb, "ms", "sampling period", NULL);
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);
else create_graph(&input, input.name+1, sampling_period, min, max, xmin, xmax, lmax, verbatim);
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);
else create_graph(inputs, inputs[0].name+1, sampling_period, ymin, ymax, xmin, xmax, lmax, verbatim);
return (status);
}
......@@ -20,7 +20,7 @@ double min, max;
enum {RUN, PAUSE};
int status=RUN;
void refresh_period_cb(char const*argument, void*){
void refresh_period_cb(char *argument, void*){
sampling_period=strtol(argument, NULL, 10)*1000;
}
......
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