示例#1
0
/*! parse an ADIF record
 *
 * the first record found in data is returned as a SQL log record
 * Designed for WSJTX ADIF ouput, may not work well on more general
 *   ADIF sources.
 *  @todo validate each field and return a bool
 */
bool ADIFParse::parse(QByteArray data, Qso *qso)
{
    const QByteArray token_names[] = { "CALL",
                                       "GRIDSQUARE",
                                       "MODE",
                                       "QSO_DATE_OFF",
                                       "TIME_OFF",
                                       "BAND",
                                       "FREQ"};
    const int n_token_names = 7;

    // only common and WSJTX modes will be matched
    const QByteArray mode_name[] = { "AM",
                                     "CW",
                                     "FM",
                                     "SSB",
                                     "USB",
                                     "LSB",
                                     "FT8",
                                     "ISCAT",
                                     "JT4",
                                     "JT9",
                                     "JT65",
                                     "MSK144",
                                     "QRA64",
                                     "RTTY"};
    const rmode_t modes[] = { RIG_MODE_AM,
                              RIG_MODE_CW,
                              RIG_MODE_FM,
                              RIG_MODE_USB,
                              RIG_MODE_USB,
                              RIG_MODE_LSB,
                              RIG_MODE_RTTY,
                              RIG_MODE_RTTY,
                              RIG_MODE_RTTY,
                              RIG_MODE_RTTY,
                              RIG_MODE_RTTY,
                              RIG_MODE_RTTY,
                              RIG_MODE_RTTY,
                              RIG_MODE_RTTY};
    const int n_mode_names=14;

    // bands are in the same order as in defines.h
    const QByteArray band_name[]= { "160M",
                                    "80M",
                                    "40M",
                                    "20M",
                                    "15M",
                                    "10M",
                                    "60M",
                                    "30M",
                                    "17M",
                                    "12M",
                                    "6M",
                                    "2M",
                                    "1.25M",
                                    "70CM",
                                    "33CM",
                                    "23CM"};

    qso->clear();
    data=data.toUpper();
    int end=data.indexOf("<EOR>");
    int start=data.indexOf("<EOH>");
    if (start==-1) {
        start=0;
    } else {
        start+=5;
    }
    data=data.mid(start,end-start);
    QList<QByteArray>elements=data.split('<');

    QDateTime time;
    time.setTimeSpec(Qt::UTC);
    QByteArray key,val;
    for (int i=0;i<elements.size();i++) {
        parseBit(elements.at(i),key,val);
        for (int j = 0; j < n_token_names; j++) {
            if (key == token_names[j]) {
                switch (j) {
                case 0:  // CALL
                    qso->call=val;
                    break;
                case 1: // GRID
                    qso->exch=val;
                    qso->rcv_exch[0]=val;
                    break;
                case 2: // MODE
                {
                    for (int k=0;k<n_mode_names;k++) {
                        if (val==mode_name[k]) {
                            qso->mode=modes[k];
                            qso->modeType=getModeType(modes[k]);
                            break;
                        }
                    }
                    break;
                }
                case 3: // DATE
                {
                    int y=val.mid(0,4).toInt();
                    int m=val.mid(4,2).toInt();
                    int d=val.mid(6,2).toInt();
                    time.setDate(QDate(y, m, d));
                    break;
                }
                case 4: // TIME
                {
                    int h=val.mid(0,2).toInt();
                    int m=val.mid(2,2).toInt();
                    int s=0;
                    if (val.size()==6) {
                        s=val.mid(4,2).toInt();
                    }
                    time.setTime(QTime(h,m,s));
                    break;
                }
                case 5: // BAND
                {
                    for (int k=0;k<N_BANDS;k++) {
                        if (val==band_name[k]) {
                            qso->band=k;
                            break;
                        }
                    }
                    break;
                }
                case 6: // FREQ
                    qso->freq=val.toDouble()*1000000;
                    break;
                }
            }
        }
    }
    qso->time=time;
    return true;
}
示例#2
0
  bool Output::draw(cv::Point2f ui_offset)
  {
    boost::timer t1;

    bool window_decorations_on = getSignal("decor");
    setSignal("decor", window_decorations_on);
    bm::setWindowDecorations(display, win, window_decorations_on);

    VLOG(3) << "decor draw time" << t1.elapsed(); 
    /*
    XWindowAttributes xwAttr;
    Status ret = XGetWindowAttributes( display, win, &xwAttr );
    int screen_w = xwAttr.width;
    int screen_h = xwAttr.height;


    if (ximage) XPutImage(display, win,  gc, ximage, 0, 0, 0, 0, screen_w, screen_h);
    */
 
    XWindowAttributes xwAttr, xwAttr2;
    // these don't seem to be updating x and y
    Window toplevel_parent = get_toplevel_parent(display, win);
    //Status ret = XGetWindowAttributes( display, win, &xwAttr );

    // this has the real x and y position
    Status ret = XGetWindowAttributes( display, toplevel_parent, &xwAttr );
    // this holds the 'true' width and height (the inner window not including
    // gnome decor?) the x and y are relative to the toplevel_parent
    Status ret2 = XGetWindowAttributes( display, win, &xwAttr2 );
      
    VLOG(6) << name  
        << " top  " << xwAttr.x << " " << xwAttr.y << ", " 
        << xwAttr.width << " " << xwAttr.height
        << " win " << xwAttr2.x << " " << xwAttr2.y << ", " 
        << xwAttr2.width << " " << xwAttr2.height;

    // TBD the user ought to be able to force x,y,w,h changes
    // the logic would be that if the window attributes disagree with the last
    // update, use those, if the getSignal value is different than the old signal,
    // that means the user wants the window resized
    
    int wm_x = xwAttr.x; // + xwAttr2.x;
    int wm_y = xwAttr.y; // + xwAttr2.y;

    if (
        (x != wm_x) ||
        (y != wm_y) ||
        (w != xwAttr2.width) ||
        (h != xwAttr2.height) 
       )
    {
      // don't do anything, the window is already set properly
      x = wm_x;
      y = wm_y;
      w = xwAttr2.width;
      h = xwAttr2.height;
      VLOG(6) << name << " wm changed display " 
        << x << " " << y << ", " << w << " " << h;

      setSignal("x", x);
      setSignal("y", y);
      setSignal("w", w);
      setSignal("h", h);

    } else {
      // see if user changed anything through vimjay interface,
      // this has lower priority than window manager changes
      int new_x = getSignal("x");
      int new_y = getSignal("y");
      int new_w = getSignal("w");
      int new_h = getSignal("h");
      
      if (
        (x != new_x) ||
        (y != new_y) ||
        (w != new_w) ||
        (h != new_h) 
        )
      {
        VLOG(6) << name << " vimjay changed display "
            << CLVAL << new_x << " " << new_y << ", " << new_w << " " << new_h << CLNRM
            << ", old " 
            << CLVAL << x << " " << y << ", " << w << " " << h << CLNRM;
        //int dx = new_x - x;
        //int dy = new_y - y;
        x = new_x;
        y = new_y;
        w = new_w;
        h = new_h;

        XWindowChanges values;
        unsigned int value_mask = 0x0;
        
        values.x = x;
        values.y = y;
        // if the window is crammed against the right border, increasing width
        // results in shrinking the window which is strange 
        values.width = w;
        values.height = h;
        
        VLOG(6) << values.x << " " << values.y;
        // TBD test if different
        {
          value_mask = CWWidth | CWHeight;
          value_mask |= CWX | CWY;
          XConfigureWindow( display, win, value_mask, &values);
        }

        // TBD if (win != toplevel_parent)
        { 
          // TBD hack, the difference between the toplevel window and the 
          // actual one are overcome by giving all of the offset to win zeroing
          // out the toplevel, when the wm changes the position it all goes to the toplevel.
          values.x = 0;
          values.y = 0;
          value_mask = CWX | CWY;
          XConfigureWindow( display, toplevel_parent, value_mask, &values);
        }
       
        setSignal("x", x);
        setSignal("y", y);
        setSignal("w", w);
        setSignal("h", h);

      } // see if vimjay ui change xywh

    } // xywh changes


    cv::Mat in = getImage("in");
    //if (in.empty()) return true;

    if (!(in.empty()) && ximage) {
    
    // These aren't used, just provided for convenience
    // and are set here to make sure the user didn't try to override them
    // (TBD set to be unwriteable when that functionality is supported
    setSignal("im_w", Config::inst()->im_width);
    setSignal("im_h", Config::inst()->im_height);
    
    VLOG(4) << "attr time" << t1.elapsed(); 

    // TBD is this necessary or does X do it for me if the window is resized?
    const cv::Size sz = cv::Size(w, h);
    cv::Mat scaled;
    if (sz == in.size()) 
      scaled = in.clone();
    else
      cv::resize(in, scaled, sz, 0, 0, getModeType() );
   
    VLOG(5) << "resize time" << t1.elapsed();

    XDestroyImage(ximage);
    ximage = XGetImage(display, DefaultRootWindow(display), 0, 0, w, h, AllPlanes, ZPixmap);
    
    VLOG(4) << "get im time" << t1.elapsed();
    // this is slow
    bm::matToXImage(scaled, ximage, win, *display, *screen);
    VLOG(4) << "matToXImage time" << t1.elapsed();
    
    XPutImage(display, win,  gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height);
    VLOG(3) << "put image time" << t1.elapsed();
    } // ximage and input image is valid

    return ImageNode::draw(ui_offset);
  }
示例#3
0
文件: output.cpp 项目: lucasw/vimjay
bool Output::draw(cv::Point2f ui_offset)
{
  boost::timer t1;

  bool is_valid = false;
  bool is_dirty = false;
  const bool window_decorations_on = getSignal("decor", is_valid, is_dirty);
  if (is_dirty)
  {
    setSignal("decor", window_decorations_on);
  }

  cv_bridge::CvImage cv_image;
  cv_image.header.stamp = ros::Time::now();
  cv_image.image = getImage("in");
  cv_image.encoding = "rgba8";
  sensor_msgs::ImagePtr msg = cv_image.toImageMsg();

  /*
  sensor_msgs::CameraInfoPtr
      camera_info(new sensor_msgs::CameraInfo(camera_info_manager_->getCameraInfo()));

  camera_info->height = cv_image.image.cols;
  camera_info->width = cv_image.image.rows;
  camera_info->header.stamp = cv_image.header.stamp;
  camera_info->header.seq = seq_++;
  */
  pub_.publish(msg);  //, camera_info);

  ROS_DEBUG_STREAM_COND(log_level > 4, "decor draw time" << t1.elapsed());

#if 0
  XWindowAttributes xwAttr, xwAttr2;
  // these don't seem to be updating x and y
  // Status ret = XGetWindowAttributes( display, win, &xwAttr );

  /*
   Occasionally getting this error if decorate/undecorate multiple times.
   I could set own XSetErrorHandler(), and there are suggestions to XSync
   or
     X Error of failed request:  BadWindow (invalid Window parameter)
     Major opcode of failed request:  3 (X_GetWindowAttributes)
     Resource id in failed request:  0x14030e7
     Serial number of failed request:  3334
     Current serial number in output stream:  3335
     [Thread 0x7ffff7f9b7c0 (LWP 4483) exited]
     [Inferior 1 (process 4483) exited with code 01]

   * */

  // this has the real x and y position,
  // but does turning off decorations cause this to change?
  ROS_DEBUG_STREAM_COND(log_level > 2, name << " 1 top " << toplevel_parent);
  Status ret = XGetWindowAttributes(display, toplevel_parent, &xwAttr);
  if (ret == 0)
  {
    ROS_ERROR_STREAM("bad xgetwindowattributes");
    return false;
  }

  if (win == toplevel_parent)
  {
    xwAttr2 = xwAttr;
  }
  else
  {
    // this holds the 'true' width and height (the inner window not including
    // gnome decor?) the x and y are relative to the toplevel_parent
    ROS_DEBUG_STREAM_COND(log_level > 2, name << " 2 win " << win);
    Status ret2 = XGetWindowAttributes(display, win, &xwAttr2);
    if (ret2 == 0)
    {
      ROS_ERROR_STREAM("bad xgetwindowattributes");
      return false;
    }
  }

  ROS_DEBUG_STREAM_COND(log_level > 6, name
                        << " top  " << xwAttr.x << " " << xwAttr.y << ", "
                        << xwAttr.width << " " << xwAttr.height
                        << " win " << xwAttr2.x << " " << xwAttr2.y << ", "
                        << xwAttr2.width << " " << xwAttr2.height);

  // TBD the user ought to be able to force x,y,w,h changes
  // the logic would be that if the window attributes disagree with the last
  // update, use those, if the getSignal value is different than the old signal,
  // that means the user wants the window resized

  int wm_x = xwAttr.x; // + xwAttr2.x;
  int wm_y = xwAttr.y; // + xwAttr2.y;

  if (
    (x != wm_x) ||
    (y != wm_y) ||
    (w != xwAttr2.width) ||
    (h != xwAttr2.height)
  )
  {
    // don't do anything, the window is already set properly
    x = wm_x;
    y = wm_y;
    w = xwAttr2.width;
    h = xwAttr2.height;
    ROS_DEBUG_STREAM_COND(log_level > 2, name << " wm changed display "
                          << x << " " << y << ", " << w << " " << h);

    setSignal("x", x);
    setSignal("y", y);
    setSignal("w", w);
    setSignal("h", h);

  }
  else
  {
    // see if user changed anything through vimjay interface,
    // this has lower priority than window manager changes
    int new_x = getSignal("x");
    int new_y = getSignal("y");
    int new_w = getSignal("w");
    int new_h = getSignal("h");

    if (
      (x != new_x) ||
      (y != new_y) ||
      (w != new_w) ||
      (h != new_h)
    )
    {
      ROS_DEBUG_STREAM_COND(log_level > 2, name << " vimjay changed display "
                            << CLVAL << new_x << " " << new_y << ", " << new_w << " " << new_h << CLNRM
                            << ", old "
                            << CLVAL << x << " " << y << ", " << w << " " << h << CLNRM);
      // int dx = new_x - x;
      // int dy = new_y - y;
      x = new_x;
      y = new_y;
      w = new_w;
      h = new_h;

      XWindowChanges values;
      unsigned int value_mask = 0x0;

      values.x = x;
      values.y = y;
      // if the window is crammed against the right border, increasing width
      // results in shrinking the window which is strange
      values.width = w;
      values.height = h;

      ROS_DEBUG_STREAM_COND(log_level > 6, values.x << " " << values.y);
      // TBD test if different
      {
        value_mask = CWWidth | CWHeight;
        value_mask |= CWX | CWY;
        XConfigureWindow(display, win, value_mask, &values);
      }

      // TBD if (win != toplevel_parent)
      {
        // TBD hack, the difference between the toplevel window and the
        // actual one are overcome by giving all of the offset to win zeroing
        // out the toplevel, when the wm changes the position it all goes to the toplevel.
        values.x = 0;
        values.y = 0;
        value_mask = CWX | CWY;
        XConfigureWindow(display, toplevel_parent, value_mask, &values);
      }

      setSignal("x", x);
      setSignal("y", y);
      setSignal("w", w);
      setSignal("h", h);

    } // see if vimjay ui change xywh

  } // xywh changes


  cv::Mat in = getImage("in");
  // if (in.empty()) return true;

  if (!(in.empty()) && ximage)
  {

    // These aren't used, just provided for convenience
    // and are set here to make sure the user didn't try to override them
    // (TBD set to be unwriteable when that functionality is supported
    setSignal("im_w", Config::inst()->im_width);
    setSignal("im_h", Config::inst()->im_height);

    ROS_DEBUG_STREAM_COND(log_level > 5, "attr time" << t1.elapsed());

    // TBD is this necessary or does X do it for me if the window is resized?
    const cv::Size sz = cv::Size(w, h);
    cv::Mat scaled;
    if (sz == in.size())
      scaled = in.clone();
    else
      cv::resize(in, scaled, sz, 0, 0, getModeType());

    ROS_DEBUG_STREAM_COND(log_level > 6, "resize time" << t1.elapsed());

    XDestroyImage(ximage);
    ximage = XGetImage(display, DefaultRootWindow(display), 0, 0, w, h, AllPlanes, ZPixmap);

    ROS_DEBUG_STREAM_COND(log_level > 5, "get im time" << t1.elapsed());
    // this is slow
    bm::matToXImage(scaled, ximage, win, *display, *screen);
    ROS_DEBUG_STREAM_COND(log_level > 5, "matToXImage time" << t1.elapsed());

    XPutImage(display, win,  gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height);
    ROS_DEBUG_STREAM_COND(log_level > 4, "put image time" << t1.elapsed());
  } // ximage and input image is valid
#endif

  return ImageNode::draw(ui_offset);
}
示例#4
0
bool ContourFlip::update()
{
  //if (!ImageNode::update()) return false;
  if (!Contour::update()) return false;

  // TBD get dirtiness of in to see if flip map needs to be recomputed
  
  if (!isDirty(this, 23)) { return true;}

  cv::Mat to_flip = getImage("to_flip");
  if (to_flip.empty()) {
    VLOG(2) << name << " in is empty";
    return false;
  }
  
  cv::Mat flipped = cv::Mat(to_flip.size(), to_flip.type());
 
  bool valid;
  bool is_dirty;
  cv::Mat in = getImage("in", valid, is_dirty, 51);
  
  if (is_dirty) 
  {
  
  LOG(INFO) << "contour flip updating " << is_dirty;
  cv::Mat dist = cv::Mat(to_flip.size(), to_flip.type());

  const int wd = dist.cols;
  const int ht = dist.rows;

  // This is very slow for dense contours, maybe make
  // scale option that will process the image at a lower resolution 
  // then upscale the off_x,off_y for the remap
  for (int y = 0; y < ht; y++) {
  for (int x = 0; x < wd; x++) {

  float min_dist = 1e9;
  cv::Point2f min_closest;

  int count = 0;
  // TBD just find the nearest contour point for now, don't worry about long segment
  // or the actual normal of the segment - just flip the pixel on the nearest point
  for (int i = 0; i < contours0.size(); i++) {  
  for (int j = 0; j < contours0[i].size(); j++) { 
  
    cv::Point2f v = contours0[i][j]; 
    cv::Point2f w = contours0[i][ (j+1) % contours0[i].size() ]; 
    //const float dx = (contours0[i][j].x - x); 
    //const float dy = (contours0[i][j].y - y);
    //const float cur_dist = fabs(dx) + fabs(dy); 
    //const float cur_dist = sqrt(dx*dx + dy*dy);
    cv::Point2f closest;
    const float cur_dist = minimum_distance( v, w, cv::Point2f(x, y), closest ); 
    if (cur_dist < min_dist) {
      min_dist = cur_dist;
      min_closest = closest;
    }
    count++;
  }}

  if ( (x == 0) && ( y == 0) ) setSignal("count", count);

  // TBD make a reflection effect instead of straight rolling over the edges?
  const int src_x = ((x + (int) ( 2 * (min_closest.x - x) ) ) + wd) % wd; 
  const int src_y = ((y + (int) ( 2 * (min_closest.y - y) ) ) + ht) % ht;
 
  // TBD this could be a map for remap and if the in image doesn't change it will
  // be more efficient
  //flipped.at<cv::Vec4b>(y, x) = to_flip.at<cv::Vec4b>(src_y, src_x);
  off_x.at<float>(y, x) = src_x - x;
  off_y.at<float>(y, x) = src_y - y;
  //LOG_FIRST_N(INFO,20) << src_x << " " << x << ", " << src_y << " " << y;
  dist.at<cv::Vec4b>(y, x) = cv::Scalar::all(min_dist); // % 255);
  }}

  cv::Mat dist_x = base_x + (off_x); //_scaled - offsetx * scalex);
  cv::Mat dist_y = base_y + (off_y); //_scaled - offsety * scaley);

  cv::convertMaps(dist_x, dist_y, dist_xy16, dist_int, CV_16SC2, true);
  
  setImage("dist", dist);

  {
    cv::Mat dist_xy8;
    cv::Mat dist_xy16_temp;
    cv::convertMaps(off_x, off_y, dist_xy16_temp, dist_int, CV_16SC2, true);
    dist_xy16_temp.convertTo(dist_xy8, CV_8UC2, getSignal("map_scale"));
    cv::Mat mapx = cv::Mat( Config::inst()->getImSize(), CV_8UC4, cv::Scalar(0,0,0,0));
    cv::Mat mapy = cv::Mat( Config::inst()->getImSize(), CV_8UC4, cv::Scalar(0,0,0,0));

    int chx[] = {0,0, 0,1, 0,2};
    mixChannels(&dist_xy8, 1, &mapx, 1, chx, 3 );
    int chy[] = {1,0, 1,1, 1,2};
    mixChannels(&dist_xy8, 1, &mapy, 1, chy, 3 );

    setImage("mapx", mapx);
    setImage("mapy", mapy);
  }

  }
  
 
  if (!dist_xy16.empty()) 
    cv::remap(to_flip, flipped, dist_xy16, cv::Mat(), getModeType(), getBorderType());

  setImage("flipped", flipped);

  return true;
}