00001
00002
00003
00004
00005
00006
00007 #include "dish_viz/DishVisualizer.h"
00008
00009 #define RADIUS 20
00010 #define P_WIDTH ((7 * RADIUS) + (8 * (2 * RADIUS)) + (2 * RADIUS))
00011 #define P_HEIGHT P_WIDTH
00012 #define X_STEP (3*RADIUS)
00013 #define Y_STEP X_STEP
00014 #define START_X (2*RADIUS)
00015 #define START_Y START_X
00016 #define ROWS 8
00017 #define COLS ROWS
00018
00019 DishVisualizer::DishVisualizer() {
00020 isInit = FALSE;
00021 plot_ca = false;
00022 data.assign(60, 0);
00023 for (int i = 0; i < 60; i++)
00024 {
00025 baselines[i] = 0.0;
00026 thresholds[i] = 0.0;
00027 min_volts[i] = 0.0;
00028 max_volts[i] = 0.0;
00029 }
00030 }
00031
00032 DishVisualizer::~DishVisualizer() {
00033 isInit = FALSE;
00034 }
00035
00041 int DishVisualizer::init(int mode) {
00042 isInit = FALSE;
00043
00044
00045 if (mode >= 0 && mode <= 3)
00046 {
00047 color_mode = mode;
00048 ROS_INFO("Visualizer color mode set to %d", color_mode);
00049 }
00050 else
00051 {
00052 color_mode = RED_BLUE_SEPARATED;
00053 ROS_WARN("Color mode (%d) is out of range [0...3]", mode);
00054 }
00055
00056
00057 PlotterParams plotter_params;
00058
00059 ostringstream oss;
00060 oss << P_WIDTH << "x" << P_HEIGHT;
00061 plotter_params.setplparam("BITMAPSIZE", (void*) oss.str().c_str());
00062
00063 plotter_params.setplparam("USE_DOUBLE_BUFFERING", (char *) "yes");
00064
00065
00066 plotter = new XPlotter(stdin, stdout, stderr, plotter_params);
00067
00068 if (plotter->openpl() < 0)
00069 {
00070 ROS_FATAL("Couldn't open Plotter");
00071 return 1;
00072 }
00073
00074 plotter->space(0, 0, P_WIDTH, P_HEIGHT);
00075 plotter->flinewidth(0.01);
00076 plotter->filltype(1);
00077 plotter->bgcolor(0, 0, 0);
00078 plotter->erase();
00079
00080 for (int row = ROWS - 1; row >= 0; row--) {
00081 for (int col = 0; col < COLS; col++) {
00082
00083 if (!((row == 0 && col == 0) || (row == ROWS - 1 && col == COLS - 1)
00084 || (row == 0 && col == COLS - 1)
00085 || (row == ROWS - 1 && col == 0))) {
00086
00087
00088 int xPos = START_X + (col * X_STEP);
00089 int yPos = START_Y + (row * Y_STEP);
00090
00091
00092 vector<int> tmp;
00093 tmp.push_back(xPos);
00094 tmp.push_back(yPos);
00095 centers.push_back(tmp);
00096 plotter->color(65535, 0, 0);
00097 plotter->circle(xPos, yPos, RADIUS);
00098 }
00099 }
00100 }
00101
00102
00103 plotter->pencolorname("white");
00104 plotter->line(P_WIDTH / 2, 0, P_WIDTH / 2, P_HEIGHT);
00105 plotter->line(0, P_HEIGHT / 2, P_WIDTH, P_HEIGHT / 2);
00106 plotter->endpath();
00107
00108 plotter->erase();
00109
00110
00111 boost::thread visualUpdate(&DishVisualizer::redraw, this);
00112
00113 isInit = TRUE;
00114 return 0;
00115
00116 }
00117
00127 int DishVisualizer::intMap(double input, double min_in, double max_in,
00128 int min_out, int max_out) {
00129 int retVal = 0;
00130
00131 if (input > max_in) {
00132 input = max_in;
00133 } else if (input < min_in) {
00134 input = min_in;
00135 }
00136
00137
00138 retVal = (int) ((input - (float) min_in) * (max_out - min_out)
00139 / ((float) max_in - (float) min_in) + min_out);
00140 return retVal;
00141 }
00142
00146 void DishVisualizer::redraw() {
00147 while (isInit) {
00148 for (uint showChan = 0; showChan < data.size(); showChan++) {
00149 uint16_t red = 0;
00150 uint16_t green = 0;
00151 uint16_t blue = 0;
00152
00153 switch (color_mode)
00154 {
00155
00156
00157
00158 case RED_BLUE_SEPARATED:
00159 if (data[showChan] <= thresholds[showChan])
00160 red = intMap(data[showChan], min_volts[showChan],
00161 thresholds[showChan], MAX_COLOR / 2, 0);
00162 else
00163 blue = MAX_COLOR;
00164 break;
00165
00166
00167
00168
00169
00170 case RED_BLUE_MIX:
00171 red = intMap(data[showChan], min_volts[showChan],
00172 max_volts[showChan], MAX_COLOR, 0);
00173 blue = intMap(data[showChan], min_volts[showChan],
00174 max_volts[showChan], 0, MAX_COLOR);
00175 break;
00176
00177
00178
00179
00180
00181
00182 case RED_GREEN_BLUE:
00183 if (data[showChan] <= baselines[showChan])
00184 red = intMap(data[showChan], min_volts[showChan],
00185 thresholds[showChan], MAX_COLOR, 0);
00186 else if (data[showChan] <= thresholds[showChan])
00187 green = intMap(data[showChan], min_volts[showChan],
00188 thresholds[showChan], MAX_COLOR, 0);
00189 else
00190 blue = MAX_COLOR;
00191 break;
00192
00193
00194
00195
00196 case BLUE_ONLY:
00197 if (data[showChan] > thresholds[showChan])
00198 blue = MAX_COLOR;
00199 break;
00200
00201 default:
00202 ROS_ERROR("Color mode (%d) is out of range [0...3]",
00203 color_mode);
00204 color_mode = RED_BLUE_SEPARATED;
00205 break;
00206 }
00207
00208 plotter->color(red, green, blue);
00209
00210
00211 int xPos = centers[showChan][0];
00212 int yPos = centers[showChan][1];
00213
00214
00215 plotter->circle(xPos, yPos, RADIUS);
00216 }
00217
00218
00219 if (plot_ca)
00220 {
00221 int x_coord = static_cast<int>((ca.x - 4.5) * X_STEP) + P_WIDTH / 2;
00222 int y_coord = P_HEIGHT / 2 - static_cast<int>((ca.y - 4.5) * Y_STEP);
00223
00224 plotter->colorname("orange");
00225 plotter->circle(x_coord, y_coord, RADIUS);
00226
00227 plot_ca = false;
00228 }
00229
00230
00231 plotter->pencolorname("white");
00232 plotter->line(P_WIDTH / 2, 0, P_WIDTH / 2, P_HEIGHT);
00233 plotter->line(0, P_HEIGHT / 2, P_WIDTH, P_HEIGHT / 2);
00234 plotter->endpath();
00235
00236 plotter->erase();
00237
00238 boost::this_thread::sleep(boost::posix_time::millisec(16));
00239 }
00240 }
00241
00247 void DishVisualizer::update(int channel, double newValue) {
00248 if (isInit) {
00249 boost::mutex::scoped_lock lock(dataUpdate);
00250 data[channel]= newValue;
00251
00252 } else {
00253 ROS_ERROR("Visualizer attempted to be updated while not initialized");
00254 }
00255 }
00256
00261 void DishVisualizer::updateCa(const burst_calc::ca& c)
00262 {
00263 if (isInit)
00264 {
00265 boost::mutex::scoped_lock lock(dataUpdate);
00266 ca = c;
00267 plot_ca = true;
00268 }
00269 else
00270 ROS_ERROR("Visualizer attempted to be updated while not initialized");
00271 }
00272
00280 void DishVisualizer::setVoltRanges(const boost::array<double, 60>& b,
00281 const boost::array<double, 60>& t,
00282 const boost::array<double, 60>& min,
00283 const boost::array<double, 60>& max)
00284 {
00285 for (int i = 0; i < 60; i++)
00286 {
00287 baselines[i] = b[i];
00288 thresholds[i] = t[i];
00289 min_volts[i] = min[i];
00290 max_volts[i] = max[i];
00291 }
00292 }