<commit_before>#include "testApp.h"

void testApp::setup()
{
    ofSetFrameRate(60);
    ofSetVerticalSync(true);
    ofSetLogLevel(OF_LOG_VERBOSE);

     controller.addListener(listener);
}
void testApp::update()
{
}
void testApp::draw()
{
    ofBackgroundGradient(ofColor(90, 90, 90), ofColor(30, 30, 30),  OF_GRADIENT_BAR);

    camera.begin();

    camera.end();
}
void testApp::keyPressed(int key){}
void testApp::keyReleased(int key){}
void testApp::mouseMoved(int x, int y ){}
void testApp::mouseDragged(int x, int y, int button){}
void testApp::mousePressed(int x, int y, int button){}
void testApp::mouseReleased(int x, int y, int button){}
void testApp::windowResized(int w, int h){}
void testApp::gotMessage(ofMessage msg){}
void testApp::dragEvent(ofDragInfo dragInfo){}

//--------------------------------------------------------------
void SampleListener::onInit(const Controller& controller)
{
    std::cout << "Initialized" << std::endl;
}
void SampleListener::onConnect(const Controller& controller)
{
    std::cout << "Connected" << std::endl;
    controller.enableGesture(Gesture::TYPE_CIRCLE);
    controller.enableGesture(Gesture::TYPE_KEY_TAP);
    controller.enableGesture(Gesture::TYPE_SCREEN_TAP);
    controller.enableGesture(Gesture::TYPE_SWIPE);
}

void SampleListener::onDisconnect(const Controller& controller)
{
    //Note: not dispatched when running in a debugger.
    std::cout << "Disconnected" << std::endl;
}

void SampleListener::onExit(const Controller& controller)
{
    std::cout << "Exited" << std::endl;
}

void SampleListener::onFrame(const Controller& controller)
{
    // Get the most recent frame and report some basic information
    const Frame frame = controller.frame();
    std::cout << "Frame id: " << frame.id()
                        << ", timestamp: " << frame.timestamp()
                        << ", hands: " << frame.hands().count()
                        << ", fingers: " << frame.fingers().count()
                        << ", tools: " << frame.tools().count()
                        << ", gestures: " << frame.gestures().count() << std::endl;

    if (!frame.hands().empty())
    {
        // Get the first hand
        const Hand hand = frame.hands()[0];

        // Check if the hand has any fingers
        const FingerList fingers = hand.fingers();
        if (!fingers.empty())
        {
            // Calculate the hand's average finger tip position
            Vector avgPos;
            for (int i = 0; i < fingers.count(); ++i)
            {
                avgPos += fingers[i].tipPosition();
            }
            avgPos /= (float)fingers.count();
            std::cout << "Hand has " << fingers.count()
                                << " fingers, average finger tip position" << avgPos << std::endl;
        }

        // Get the hand's sphere radius and palm position
        std::cout 	<< "Hand sphere radius: " << hand.sphereRadius()
                    << " mm, palm position: "  << hand.palmPosition() << std::endl;

        // Get the hand's normal vector and direction
        const Vector normal = hand.palmNormal();
        const Vector direction = hand.direction();

        // Calculate the hand's pitch, roll, and yaw angles
        std::cout << "Hand pitch: " << direction.pitch() * RAD_TO_DEG 	<< " degrees, "
                        << "roll: " << normal.roll() * RAD_TO_DEG << " degrees, "
                            << "yaw: " << direction.yaw() * RAD_TO_DEG << " degrees" << std::endl;
    }

    // Get gestures
    const GestureList gestures = frame.gestures();
    for (int g = 0; g < gestures.count(); ++g)
    {
        Gesture gesture = gestures[g];
        switch (gesture.type())
        {
            case Gesture::TYPE_CIRCLE:
            {
                CircleGesture circle = gesture;
                std::string clockwiseness;

                if (circle.pointable().direction().angleTo(circle.normal()) <= PI/4)
                {
                    clockwiseness = "clockwise";
                }
                else
                {
                    clockwiseness = "counterclockwise";
                }

                // Calculate angle swept since last frame
                float sweptAngle = 0;
                if (circle.state() != Gesture::STATE_START)
                {
                    CircleGesture previousUpdate = CircleGesture(controller.frame(1).gesture(circle.id()));
                    sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * PI;
                }
                std::cout 	<< "Circle id: " << gesture.id()
                            << ", state: " << gesture.state()
                            << ", progress: " << circle.progress()
                            << ", radius: " << circle.radius()
                            << ", angle " << sweptAngle * RAD_TO_DEG
                            <<  ", " << clockwiseness << std::endl;
                break;
            }
            case Gesture::TYPE_SWIPE:
            {
                SwipeGesture swipe = gesture;
                std::cout 	<< "Swipe id: "<< gesture.id()
                                  << ", state: " << gesture.state()
                                  << ", direction: "<< swipe.direction()
                                  << ", speed: " << swipe.speed() << std::endl;
                break;
            }
            case Gesture::TYPE_KEY_TAP:
            {
                KeyTapGesture tap = gesture;
                std::cout << "Key Tap id: "<< gesture.id()
                                << ", state: " << gesture.state()
                                << ", position: " << tap.position()
                                << ", direction: " << tap.direction()<< std::endl;
                break;
            }
            case Gesture::TYPE_SCREEN_TAP:
            {
                ScreenTapGesture screentap = gesture;
                std::cout << "Screen Tap id: " << gesture.id()
                                << ", state: " << gesture.state()
                                << ", position: " << screentap.position()
                                << ", direction: " << screentap.direction()<< std::endl;
                break;
            }
            default:
                std::cout << "Unknown gesture type." << std::endl;
                break;
        }
    }

    if (!frame.hands().empty() || !gestures.empty())
    {
        std::cout << std::endl;
    }
}

void SampleListener::onFocusGained(const Controller& controller)
{
    std::cout << "Focus Gained" << std::endl;
}

void SampleListener::onFocusLost(const Controller& controller)
{
    std::cout << "Focus Lost" << std::endl;
}<commit_msg>Fixed indetnation<commit_after>#include "testApp.h"

void testApp::setup()
{
    ofSetFrameRate(60);
    ofSetVerticalSync(true);
    ofSetLogLevel(OF_LOG_VERBOSE);

    controller.addListener(listener);
}
void testApp::update()
{
}
void testApp::draw()
{
    ofBackgroundGradient(ofColor(90, 90, 90), ofColor(30, 30, 30),  OF_GRADIENT_BAR);

    camera.begin();
    camera.end();
}
void testApp::keyPressed(int key){}
void testApp::keyReleased(int key){}
void testApp::mouseMoved(int x, int y ){}
void testApp::mouseDragged(int x, int y, int button){}
void testApp::mousePressed(int x, int y, int button){}
void testApp::mouseReleased(int x, int y, int button){}
void testApp::windowResized(int w, int h){}
void testApp::gotMessage(ofMessage msg){}
void testApp::dragEvent(ofDragInfo dragInfo){}

//--------------------------------------------------------------
void SampleListener::onInit(const Controller& controller)
{
    std::cout << "Initialized" << std::endl;
}
void SampleListener::onConnect(const Controller& controller)
{
    std::cout << "Connected" << std::endl;
    controller.enableGesture(Gesture::TYPE_CIRCLE);
    controller.enableGesture(Gesture::TYPE_KEY_TAP);
    controller.enableGesture(Gesture::TYPE_SCREEN_TAP);
    controller.enableGesture(Gesture::TYPE_SWIPE);
}

void SampleListener::onDisconnect(const Controller& controller)
{
    //Note: not dispatched when running in a debugger.
    std::cout << "Disconnected" << std::endl;
}

void SampleListener::onExit(const Controller& controller)
{
    std::cout << "Exited" << std::endl;
}

void SampleListener::onFrame(const Controller& controller)
{
    // Get the most recent frame and report some basic information
    const Frame frame = controller.frame();
    std::cout << "Frame id: " << frame.id()
                        << ", timestamp: " << frame.timestamp()
                        << ", hands: " << frame.hands().count()
                        << ", fingers: " << frame.fingers().count()
                        << ", tools: " << frame.tools().count()
                        << ", gestures: " << frame.gestures().count() << std::endl;

    if (!frame.hands().empty())
    {
        // Get the first hand
        const Hand hand = frame.hands()[0];

        // Check if the hand has any fingers
        const FingerList fingers = hand.fingers();
        if (!fingers.empty())
        {
            // Calculate the hand's average finger tip position
            Vector avgPos;
            for (int i = 0; i < fingers.count(); ++i)
            {
                avgPos += fingers[i].tipPosition();
            }
            avgPos /= (float)fingers.count();
            std::cout << "Hand has " << fingers.count()
                                << " fingers, average finger tip position" << avgPos << std::endl;
        }

        // Get the hand's sphere radius and palm position
        std::cout 	<< "Hand sphere radius: " << hand.sphereRadius()
                    << " mm, palm position: "  << hand.palmPosition() << std::endl;

        // Get the hand's normal vector and direction
        const Vector normal = hand.palmNormal();
        const Vector direction = hand.direction();

        // Calculate the hand's pitch, roll, and yaw angles
        std::cout << "Hand pitch: " << direction.pitch() * RAD_TO_DEG 	<< " degrees, "
                        << "roll: " << normal.roll() * RAD_TO_DEG << " degrees, "
                            << "yaw: " << direction.yaw() * RAD_TO_DEG << " degrees" << std::endl;
    }

    // Get gestures
    const GestureList gestures = frame.gestures();
    for (int g = 0; g < gestures.count(); ++g)
    {
        Gesture gesture = gestures[g];
        switch (gesture.type())
        {
            case Gesture::TYPE_CIRCLE:
            {
                CircleGesture circle = gesture;
                std::string clockwiseness;

                if (circle.pointable().direction().angleTo(circle.normal()) <= PI/4)
                {
                    clockwiseness = "clockwise";
                }
                else
                {
                    clockwiseness = "counterclockwise";
                }

                // Calculate angle swept since last frame
                float sweptAngle = 0;
                if (circle.state() != Gesture::STATE_START)
                {
                    CircleGesture previousUpdate = CircleGesture(controller.frame(1).gesture(circle.id()));
                    sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * PI;
                }
                std::cout 	<< "Circle id: " << gesture.id()
                            << ", state: " << gesture.state()
                            << ", progress: " << circle.progress()
                            << ", radius: " << circle.radius()
                            << ", angle " << sweptAngle * RAD_TO_DEG
                            <<  ", " << clockwiseness << std::endl;
                break;
            }
            case Gesture::TYPE_SWIPE:
            {
                SwipeGesture swipe = gesture;
                std::cout 	<< "Swipe id: "<< gesture.id()
                                  << ", state: " << gesture.state()
                                  << ", direction: "<< swipe.direction()
                                  << ", speed: " << swipe.speed() << std::endl;
                break;
            }
            case Gesture::TYPE_KEY_TAP:
            {
                KeyTapGesture tap = gesture;
                std::cout << "Key Tap id: "<< gesture.id()
                                << ", state: " << gesture.state()
                                << ", position: " << tap.position()
                                << ", direction: " << tap.direction()<< std::endl;
                break;
            }
            case Gesture::TYPE_SCREEN_TAP:
            {
                ScreenTapGesture screentap = gesture;
                std::cout << "Screen Tap id: " << gesture.id()
                                << ", state: " << gesture.state()
                                << ", position: " << screentap.position()
                                << ", direction: " << screentap.direction()<< std::endl;
                break;
            }
            default:
                std::cout << "Unknown gesture type." << std::endl;
                break;
        }
    }

    if (!frame.hands().empty() || !gestures.empty())
    {
        std::cout << std::endl;
    }
}

void SampleListener::onFocusGained(const Controller& controller)
{
    std::cout << "Focus Gained" << std::endl;
}

void SampleListener::onFocusLost(const Controller& controller)
{
    std::cout << "Focus Lost" << std::endl;
}<|endoftext|>


<commit_before>/*
   Min Kao Drone Tour
   Modified by Elliot Greenlee
 */

#include "objectFollowing.h"
#include "../control.h"
#include <string>
using namespace std;

const string THRESHOLDS_FILE_NAME = "thresholds.xml";
const double dt = 1.0; //Sampling time [s]

/*
 */
ObjectFollowing::ObjectFollowing(Control *control) {
  control_ptr = control;
  kalman = cv::KalmanFilter(4, 2, 0);

  // XML save data for object following color thresholds
  cv::FileStorage fs(THRESHOLDS_FILE_NAME, cv::FileStorage::READ);

  // If there is a save file then read it
  if (fs.isOpened()) {
    maxH = fs["H_MAX"];
    minH = fs["H_MIN"];
    maxS = fs["S_MAX"];
    minS = fs["S_MIN"];
    maxV = fs["V_MAX"];
    minV = fs["V_MIN"];
    fs.release();
  }

  // Create a window
  cv::namedWindow("binalized");
  cv::createTrackbar("Hue max", "binalized", &maxH, 255);
  cv::createTrackbar("Hue min", "binalized", &minH, 255);
  cv::createTrackbar("Saturation max", "binalized", &maxS, 255);
  cv::createTrackbar("Saturation min", "binalized", &minS, 255);
  cv::createTrackbar("Value max", "binalized", &maxV, 255);
  cv::createTrackbar("Value min", "binalized", &minV, 255);
  cv::resizeWindow("binalized", 0, 0);

  // Transition matrix (x, y, vx, vy)
  cv::Mat1f A(4, 4);
  A << 1.0, 0.0,  dt, 0.0,
    0.0, 1.0, 0.0,  dt,
    0.0, 0.0, 1.0, 0.0,
    0.0, 0.0, 0.0, 1.0;
  kalman.transitionMatrix = A;

  // Measurement matrix (x, y)
  cv::Mat1f H(2, 4);
  H << 1, 0, 0, 0,
    0, 1, 0, 0;
  kalman.measurementMatrix = H;

  // Process noise covairance (x, y, vx, vy)
  cv::Mat1f Q(4, 4);
  Q << 1e-5,  0.0,  0.0,  0.0,
    0.0, 1e-5,  0.0,  0.0,
    0.0,  0.0, 1e-5,  0.0,
    0.0,  0.0,  0.0, 1e-5;
  kalman.processNoiseCov = Q;

  // Measurement noise covariance (x, y)
  cv::Mat1f R(2, 2);
  R << 1e-1,  0.0,
    0.0, 1e-1;
  kalman.measurementNoiseCov = R;
}

/*
 */
void ObjectFollowing::close() {
  //Save thresholds
  cv::FileStorage fs(THRESHOLDS_FILE_NAME, cv::FileStorage::READ);
  fs.open(THRESHOLDS_FILE_NAME, cv::FileStorage::WRITE);
  if (fs.isOpened()) {
    cv::write(fs, "H_MAX", maxH);
    cv::write(fs, "H_MIN", minH);
    cv::write(fs, "S_MAX", maxS);
    cv::write(fs, "S_MIN", minS);
    cv::write(fs, "V_MAX", maxV);
    cv::write(fs, "V_MIN", minV);
    fs.release();
  }
}

/*
   returns heading for control
 */
void ObjectFollowing::fly() {

  ControlMovements *controlMovements = &(control_ptr->velocities);
  cv::Mat *image = &(control_ptr->image);

  int tolerance = 50;
  cv::Vec3b hsvSample;
  cv::Scalar green = CV_RGB(0,255,0); //putText color value

  //switch between learning and non-learning mode
  if (control_ptr->key == 'l') {
    learnMode = !learnMode;
    if (learnMode) {
      printf("Learning mode is enabled\n");
      printf("The color at the crosshairs is being learned\n");
      printf("Press l again to turn off learning mode\n\n");
    }
    else {
      printf("Learning mode is disabled\n");
      printf("The color last at the crosshairs will be targeted\n");
      printf("Press l again to learn a different color\n\n");
    }
  }

  // HSV image
  cv::Mat hsv;
  cv::cvtColor(*image, hsv, cv::COLOR_BGR2HSV_FULL);

  // Binalize
  cv::Mat binalized;
  cv::Scalar lower(minH, minS, minV);
  cv::Scalar upper(maxH, maxS, maxV);
  cv::inRange(hsv, lower, upper, binalized);

  // Show result
  cv::imshow("binalized", binalized);

  // De-noising
  cv::Mat kernel = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
  cv::morphologyEx(binalized, binalized, cv::MORPH_CLOSE, kernel);

  // Detect contours
  vector<vector<cv::Point> > contours;
  cv::findContours(binalized.clone(), contours, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);

  // Find largest contour
  int contour_index = -1;
  double max_area = 0.0;
  for (size_t i = 0; i < contours.size(); i++) {
    double area = fabs(cv::contourArea(contours[i]));
    if (area > max_area) {
      contour_index = i;
      max_area = area;
    }
  }

  // Object detected
  if (contour_index >= 0) {

    // Moments
    cv::Moments moments = cv::moments(contours[contour_index], true);
    double marker_y = (int)(moments.m01 / moments.m00);
    double marker_x = (int)(moments.m10 / moments.m00);

    // Measurements
    cv::Mat measurement = (cv::Mat1f(2, 1) << marker_x, marker_y);

    // Correction
    cv::Mat estimated = kalman.correct(measurement);

    // Show result
    rect = cv::boundingRect(contours[contour_index]);
    cv::rectangle(*image, rect, cv::Scalar(0, 255, 0));

    // Calculate average hsv for the object within the coutour
    int avgHue = 0;
    int avgSaturation = 0;
    int avgValue = 0;
    int numPoints = 0;

    //for x in rectangle
    for (x = rect.point.x; x < rect.point.x + rect.width; x++) {
      //for y in rectangle
      for (y = rect.point.y; y < rect.point.y + rect.wdith; y++) {
        // TODO: If this is to slow, use rectangle average or do every second, third, etc point in rectangle for loop
        if (inCoutour(x, y, countours[contour_index])) {
          numPoints++;
          hsvPoint = hsv.at<cv::Vec3b>(cvPoint(x, y));
          avgHue += hsvPoint[0];
          avgSaturation += hsvPoint[1];
          avgValue += hsvPoint[2];
        }
      }
    }

    avgHue = ((double)avgHue)/numPoints;
    avgSaturation = ((double)avgSaturation)/numPoints;
    avgValue = ((double)avgValue)/numPoints;

    hsvSample[0] = avgHue;
    hsvSample[1] = avgSaturation;
    hsvSample[2] = avgValue;

    minH = avgHue - tolerance;
    maxH = avgHue + tolerance;
    minS = avgSaturation - tolerance;
    maxS = avgSaturation + tolerance;
    minV = avgValue - tolerance;
    maxV = avgValue + tolerance;
  }

  // Prediction
  cv::Mat1f prediction = kalman.predict();
  int radius = 1e+3 * kalman.errorCovPre.at<float>(0, 0);

  // Show predicted position
  cv::circle(*image, cv::Point(prediction(0, 0), prediction(0, 1)), radius, green, 2);

  // Calculate object heading fraction
  float rHeading = -(((*image).cols/2) - prediction(0, 0))/((*image).cols/2);
  float zHeading = -(((*image).rows/2) - prediction(0, 1))/((*image).rows/2);

  if (abs(rHeading) <= 0.8 && abs(zHeading) <= 0.8) {
    time_t lastSearchTime = time(0);
  }

  time_t currentTime = time(0);
  double elapsedTime = difftime(currentTime, lastSearchTime);
  if (elapsedTime >= 3) {
    ardrone.landing();
    fprintf(flight_log, "LAND\n");
  }

  // Sample the object color
  if(learnMode) {
    // Show targeting crosshairs
    cv::line(*image, cvPoint((*image).cols/2, 0), cvPoint((*image).cols/2, (*image).rows/2 - 2), green); //top vertical crosshair
    cv::line(*image, cvPoint((*image).cols/2, (*image).rows/2 + 2), cvPoint((*image).cols/2, (*image).rows), green); //bottom vertical crosshair
    cv::line(*image, cvPoint(0, (*image).rows/2), cvPoint((*image).cols/2 - 2, (*image).rows/2), green); //left horizontal crosshair
    cv::line(*image, cvPoint((*image).cols/2 + 2, (*image).rows/2), cvPoint((*image).cols, (*image).rows/2), green); //right horizontal crosshair

    hsvSample = hsv.at<cv::Vec3b>(cvPoint((*image).cols/2, (*image).rows/2));

  }
  setHSVTrackBarPositions(hsvSample[0], hsvSample[1], hsvSample[2], tolerance);

  displayObjectFollowingInfo(image, rHeading, zHeading, hsvSample[0], hsvSample[1], hsvSample[2]);

  rect_area = rect.width * rect.height;

  /*
  //Execute drone movement
  if (rect_area > 25000) {
  controlMovements->vx = -1.0;
  moveStatus = false;
  }
  else if (rect_area <= 25000 && rect_area >= 20000) {
  controlMovements->vx = 0;
  moveStatus = false;
  }
  else {
  controlMovements->vx = 1.0;
  moveStatus = true;
  }
   */

  controlMovements->vx = (goalArea - rect_area)/((double)goalArea);

  if(controlMovements->vx > 1) {
    controlMovements->vx = 1;
  }
  else if (controlMovements->vx < -1){
    controlMovements->vx = -1;
  }

  /*if( control_ptr->altitude < 1.2 )
  {
    controlMovements->vz = 1.0;
  }
  else {
    controlMovements->vz = 0.0;
  }
  */

  time_t current_time = time(0);
  double elapsed_time = difftime(current_time, control_ptr->takeoff_time);
  if (elapsed_time < 5){
    controlMovements->vx = 0;
    controlMovements->vy = 0;
    controlMovements->vz = 0;
    controlMovements->vr = 0;
  } else {
    controlMovements->vz = -(zHeading * 0.2);
    controlMovements->vr = -(rHeading * 0.5);
  }

  return;
}

//Auto set Hue, Saturation, and Value tracking bars
void setHSVTrackBarPositions(int hue, int saturation, int value, int tolerance) {
  cv::setTrackbarPos("Hue max", "binalized", hue + tolerance);
  cv::setTrackbarPos("Hue min", "binalized", hue - tolerance);

  cv::setTrackbarPos("Saturation max", "binalized", saturation + tolerance);
  cv::setTrackbarPos("Saturation min", "binalized", saturation - tolerance);

  cv::setTrackbarPos("Value max", "binalized", value + tolerance);
  cv::setTrackbarPos("Value min", "binalized", value - tolerance);

}

/*
 */
void ObjectFollowing::displayObjectFollowingInfo(cv::Mat *image, double rHeading, double zHeading, int hue, int saturation, int value) {
  char rHeadingDisplay[80]; //print buffer for rHeading
  char zHeadingDisplay[80]; //print buffer for zHeading
  char hsvSampleDisplay[80]; //print buffer for learning HSV values
  char moveStatusDisplay[80]; //print buffer for stop/go status

  cv::Scalar green = CV_RGB(0,255,0); //putText color value

  sprintf(rHeadingDisplay, "rHeading = %+3.2f", rHeading);
  sprintf(zHeadingDisplay, "zHeading = %+3.2f", zHeading);
  sprintf(hsvSampleDisplay, "hsvSample = %3d, %3d, %3d", hue, saturation, value);
  if (moveStatus) {
    sprintf(moveStatusDisplay, "move status = GO");
  }
  else {
    sprintf(moveStatusDisplay, "move status = STOP");
  }

  putText(*image, rHeadingDisplay, cvPoint(30, 120), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);
  putText(*image, zHeadingDisplay, cvPoint(30, 140), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);
  putText(*image, hsvSampleDisplay, cvPoint(30, 160), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);
  putText(*image, moveStatusDisplay, cvPoint(30, 180), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);

}

/*
*/
boolean inContour(int x, int y, Contour c){
  Point p = new Point(x,y);
  MatOfPoint2f m = new MatOfPoint2f(c.pointMat.toArray());

  double r = Imgproc.pointPolygonTest(m,p, false);

  return r == 1;
}
<commit_msg>Fixed objectFollowing to compile.<commit_after>/*
   Min Kao Drone Tour
   Modified by Elliot Greenlee
 */

#include "objectFollowing.h"
#include "../control.h"
#include <string>
using namespace std;

const string THRESHOLDS_FILE_NAME = "thresholds.xml";
const double dt = 1.0; //Sampling time [s]

/*
 */
ObjectFollowing::ObjectFollowing(Control *control) {
  control_ptr = control;
  kalman = cv::KalmanFilter(4, 2, 0);

  // XML save data for object following color thresholds
  cv::FileStorage fs(THRESHOLDS_FILE_NAME, cv::FileStorage::READ);

  // If there is a save file then read it
  if (fs.isOpened()) {
    maxH = fs["H_MAX"];
    minH = fs["H_MIN"];
    maxS = fs["S_MAX"];
    minS = fs["S_MIN"];
    maxV = fs["V_MAX"];
    minV = fs["V_MIN"];
    fs.release();
  }

  // Create a window
  cv::namedWindow("binalized");
  cv::createTrackbar("Hue max", "binalized", &maxH, 255);
  cv::createTrackbar("Hue min", "binalized", &minH, 255);
  cv::createTrackbar("Saturation max", "binalized", &maxS, 255);
  cv::createTrackbar("Saturation min", "binalized", &minS, 255);
  cv::createTrackbar("Value max", "binalized", &maxV, 255);
  cv::createTrackbar("Value min", "binalized", &minV, 255);
  cv::resizeWindow("binalized", 0, 0);

  // Transition matrix (x, y, vx, vy)
  cv::Mat1f A(4, 4);
  A << 1.0, 0.0,  dt, 0.0,
    0.0, 1.0, 0.0,  dt,
    0.0, 0.0, 1.0, 0.0,
    0.0, 0.0, 0.0, 1.0;
  kalman.transitionMatrix = A;

  // Measurement matrix (x, y)
  cv::Mat1f H(2, 4);
  H << 1, 0, 0, 0,
    0, 1, 0, 0;
  kalman.measurementMatrix = H;

  // Process noise covairance (x, y, vx, vy)
  cv::Mat1f Q(4, 4);
  Q << 1e-5,  0.0,  0.0,  0.0,
    0.0, 1e-5,  0.0,  0.0,
    0.0,  0.0, 1e-5,  0.0,
    0.0,  0.0,  0.0, 1e-5;
  kalman.processNoiseCov = Q;

  // Measurement noise covariance (x, y)
  cv::Mat1f R(2, 2);
  R << 1e-1,  0.0,
    0.0, 1e-1;
  kalman.measurementNoiseCov = R;
}

/*
 */
void ObjectFollowing::close() {
  //Save thresholds
  cv::FileStorage fs(THRESHOLDS_FILE_NAME, cv::FileStorage::READ);
  fs.open(THRESHOLDS_FILE_NAME, cv::FileStorage::WRITE);
  if (fs.isOpened()) {
    cv::write(fs, "H_MAX", maxH);
    cv::write(fs, "H_MIN", minH);
    cv::write(fs, "S_MAX", maxS);
    cv::write(fs, "S_MIN", minS);
    cv::write(fs, "V_MAX", maxV);
    cv::write(fs, "V_MIN", minV);
    fs.release();
  }
}

/*
   returns heading for control
 */
void ObjectFollowing::fly() {

  ControlMovements *controlMovements = &(control_ptr->velocities);
  cv::Mat *image = &(control_ptr->image);

  int tolerance = 50;
  cv::Vec3b hsvSample;
  cv::Scalar green = CV_RGB(0,255,0); //putText color value

  //switch between learning and non-learning mode
  if (control_ptr->key == 'l') {
    learnMode = !learnMode;
    if (learnMode) {
      printf("Learning mode is enabled\n");
      printf("The color at the crosshairs is being learned\n");
      printf("Press l again to turn off learning mode\n\n");
    }
    else {
      printf("Learning mode is disabled\n");
      printf("The color last at the crosshairs will be targeted\n");
      printf("Press l again to learn a different color\n\n");
    }
  }

  // HSV image
  cv::Mat hsv;
  cv::cvtColor(*image, hsv, cv::COLOR_BGR2HSV_FULL);

  // Binalize
  cv::Mat binalized;
  cv::Scalar lower(minH, minS, minV);
  cv::Scalar upper(maxH, maxS, maxV);
  cv::inRange(hsv, lower, upper, binalized);

  // Show result
  cv::imshow("binalized", binalized);

  // De-noising
  cv::Mat kernel = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
  cv::morphologyEx(binalized, binalized, cv::MORPH_CLOSE, kernel);

  // Detect contours
  vector<vector<cv::Point> > contours;
  cv::findContours(binalized.clone(), contours, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);

  // Find largest contour
  int contour_index = -1;
  double max_area = 0.0;
  for (size_t i = 0; i < contours.size(); i++) {
    double area = fabs(cv::contourArea(contours[i]));
    if (area > max_area) {
      contour_index = i;
      max_area = area;
    }
  }

  // Object detected
  if (contour_index >= 0) {

    // Moments
    cv::Moments moments = cv::moments(contours[contour_index], true);
    double marker_y = (int)(moments.m01 / moments.m00);
    double marker_x = (int)(moments.m10 / moments.m00);

    // Measurements
    cv::Mat measurement = (cv::Mat1f(2, 1) << marker_x, marker_y);

    // Correction
    cv::Mat estimated = kalman.correct(measurement);

    // Show result
    rect = cv::boundingRect(contours[contour_index]);
    cv::rectangle(*image, rect, cv::Scalar(0, 255, 0));

    // Calculate average hsv for the object within the coutour
    int avgHue = 0;
    int avgSaturation = 0;
    int avgValue = 0;
    int numPoints = 0;

    //for x in rectangle
    for (int x = rect.x; x < rect.x + rect.width; x++) {
      //for y in rectangle
      for (int y = rect.y; y < rect.y + rect.height; y++) {
        // TODO: If this is to slow, use rectangle average or do every second, third, etc point in rectangle for loop
        //if (inContour(x, y, contours[contour_index])) {
          cv::Point pt(x,y);
          if (rect.contains(pt)) {
          numPoints++;
          cv::Vec3b hsvPoint = hsv.at<cv::Vec3b>(cvPoint(x, y));
          avgHue += hsvPoint[0];
          avgSaturation += hsvPoint[1];
          avgValue += hsvPoint[2];
        }
      }
    }

    avgHue = ((double)avgHue)/numPoints;
    avgSaturation = ((double)avgSaturation)/numPoints;
    avgValue = ((double)avgValue)/numPoints;

    hsvSample[0] = avgHue;
    hsvSample[1] = avgSaturation;
    hsvSample[2] = avgValue;

    minH = avgHue - tolerance;
    maxH = avgHue + tolerance;
    minS = avgSaturation - tolerance;
    maxS = avgSaturation + tolerance;
    minV = avgValue - tolerance;
    maxV = avgValue + tolerance;
  }

  // Prediction
  cv::Mat1f prediction = kalman.predict();
  int radius = 1e+3 * kalman.errorCovPre.at<float>(0, 0);

  // Show predicted position
  cv::circle(*image, cv::Point(prediction(0, 0), prediction(0, 1)), radius, green, 2);

  // Calculate object heading fraction
  float rHeading = -(((*image).cols/2) - prediction(0, 0))/((*image).cols/2);
  float zHeading = -(((*image).rows/2) - prediction(0, 1))/((*image).rows/2);

  //Emergency landing
  time_t lastSearchTime = 0;
  if (abs(rHeading) <= 0.8 && abs(zHeading) <= 0.8) {
    lastSearchTime = time(0);
  }

  time_t currentTime = time(0);
  double elapsedTime = difftime(currentTime, lastSearchTime);
  if (elapsedTime >= 3) {
    control_ptr->ardrone.landing();
  }

  // Sample the object color
  if(learnMode) {
    // Show targeting crosshairs
    cv::line(*image, cvPoint((*image).cols/2, 0), cvPoint((*image).cols/2, (*image).rows/2 - 2), green); //top vertical crosshair
    cv::line(*image, cvPoint((*image).cols/2, (*image).rows/2 + 2), cvPoint((*image).cols/2, (*image).rows), green); //bottom vertical crosshair
    cv::line(*image, cvPoint(0, (*image).rows/2), cvPoint((*image).cols/2 - 2, (*image).rows/2), green); //left horizontal crosshair
    cv::line(*image, cvPoint((*image).cols/2 + 2, (*image).rows/2), cvPoint((*image).cols, (*image).rows/2), green); //right horizontal crosshair

    hsvSample = hsv.at<cv::Vec3b>(cvPoint((*image).cols/2, (*image).rows/2));

  }
  setHSVTrackBarPositions(hsvSample[0], hsvSample[1], hsvSample[2], tolerance);

  displayObjectFollowingInfo(image, rHeading, zHeading, hsvSample[0], hsvSample[1], hsvSample[2]);

  rect_area = rect.width * rect.height;

  /*
  //Execute drone movement
  if (rect_area > 25000) {
  controlMovements->vx = -1.0;
  moveStatus = false;
  }
  else if (rect_area <= 25000 && rect_area >= 20000) {
  controlMovements->vx = 0;
  moveStatus = false;
  }
  else {
  controlMovements->vx = 1.0;
  moveStatus = true;
  }
   */

  controlMovements->vx = (goalArea - rect_area)/((double)goalArea);

  if(controlMovements->vx > 1) {
    controlMovements->vx = 1;
  }
  else if (controlMovements->vx < -1){
    controlMovements->vx = -1;
  }

  /*if( control_ptr->altitude < 1.2 )
  {
    controlMovements->vz = 1.0;
  }
  else {
    controlMovements->vz = 0.0;
  }
  */

  time_t current_time = time(0);
  double elapsed_time = difftime(current_time, control_ptr->takeoff_time);
  if (elapsed_time < 5){
    controlMovements->vx = 0;
    controlMovements->vy = 0;
    controlMovements->vz = 0;
    controlMovements->vr = 0;
  } else {
    controlMovements->vz = -(zHeading * 0.2);
    controlMovements->vr = -(rHeading * 0.5);
  }

  return;
}

//Auto set Hue, Saturation, and Value tracking bars
void setHSVTrackBarPositions(int hue, int saturation, int value, int tolerance) {
  cv::setTrackbarPos("Hue max", "binalized", hue + tolerance);
  cv::setTrackbarPos("Hue min", "binalized", hue - tolerance);

  cv::setTrackbarPos("Saturation max", "binalized", saturation + tolerance);
  cv::setTrackbarPos("Saturation min", "binalized", saturation - tolerance);

  cv::setTrackbarPos("Value max", "binalized", value + tolerance);
  cv::setTrackbarPos("Value min", "binalized", value - tolerance);

}

/*
 */
void ObjectFollowing::displayObjectFollowingInfo(cv::Mat *image, double rHeading, double zHeading, int hue, int saturation, int value) {
  char rHeadingDisplay[80]; //print buffer for rHeading
  char zHeadingDisplay[80]; //print buffer for zHeading
  char hsvSampleDisplay[80]; //print buffer for learning HSV values
  char moveStatusDisplay[80]; //print buffer for stop/go status

  cv::Scalar green = CV_RGB(0,255,0); //putText color value

  sprintf(rHeadingDisplay, "rHeading = %+3.2f", rHeading);
  sprintf(zHeadingDisplay, "zHeading = %+3.2f", zHeading);
  sprintf(hsvSampleDisplay, "hsvSample = %3d, %3d, %3d", hue, saturation, value);
  if (moveStatus) {
    sprintf(moveStatusDisplay, "move status = GO");
  }
  else {
    sprintf(moveStatusDisplay, "move status = STOP");
  }

  putText(*image, rHeadingDisplay, cvPoint(30, 120), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);
  putText(*image, zHeadingDisplay, cvPoint(30, 140), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);
  putText(*image, hsvSampleDisplay, cvPoint(30, 160), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);
  putText(*image, moveStatusDisplay, cvPoint(30, 180), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, green, 1, CV_AA);

}

/*
bool inContour(int x, int y, Contour c){
  cv::Point p = new cv::Point(x,y);
  cv::MatOfPoint2f m = new cv::MatOfPoint2f(c.pointMat.toArray());

  double r = cv::Imgproc.pointPolygonTest(m,p, false);

  return r == 1;
}
*/
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2015 Canonical Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "cmakekitinformation.h"
#include "cmakekitconfigwidget.h"
#include "cmaketoolmanager.h"
#include "cmaketool.h"

#include <utils/qtcassert.h>
#include <projectexplorer/task.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/projectexplorerconstants.h>

#include <QDebug>

using namespace ProjectExplorer;

namespace CMakeProjectManager {

CMakeKitInformation::CMakeKitInformation()
{
    setObjectName(QLatin1String("CMakeKitInformation"));
    setId(CMakeKitInformation::id());

    //make sure the default value is set if a selected CMake is removed
    connect(CMakeToolManager::instance(), &CMakeToolManager::cmakeRemoved,
            [this]() { foreach (Kit *k, KitManager::kits()) fix(k); });

    //make sure the default value is set if a new default CMake is set
    connect(CMakeToolManager::instance(), &CMakeToolManager::defaultCMakeChanged,
            [this]() { foreach (Kit *k, KitManager::kits()) fix(k); });
}

Core::Id CMakeKitInformation::id()
{
    return "CMakeProjectManager.CMakeKitInformation";
}

CMakeTool *CMakeKitInformation::cmakeTool(const Kit *k)
{
    if (!k)
        return 0;

    const QVariant id = k->value(CMakeKitInformation::id());
    return CMakeToolManager::findById(Core::Id::fromSetting(id));
}

void CMakeKitInformation::setCMakeTool(Kit *k, const Core::Id id)
{
    QTC_ASSERT(k, return);

    if (id.isValid()) {
        // Only set cmake tools that are known to the manager
        QTC_ASSERT(CMakeToolManager::findById(id), return);
        k->setValue(CMakeKitInformation::id(), id.toSetting());
    } else {
        //setting a empty Core::Id will reset to the default value
        k->setValue(CMakeKitInformation::id(),defaultValue().toSetting());
    }
}

Core::Id CMakeKitInformation::defaultValue()
{
    CMakeTool *defaultTool = CMakeToolManager::defaultCMakeTool();
    if (defaultTool)
        return defaultTool->id();

    return Core::Id();
}

QVariant CMakeKitInformation::defaultValue(Kit *) const
{
    return defaultValue().toSetting();
}

QList<Task> CMakeKitInformation::validate(const Kit *k) const
{
    Q_UNUSED(k);
    return QList<Task>();
}

void CMakeKitInformation::setup(Kit *k)
{
    CMakeTool *tool = CMakeKitInformation::cmakeTool(k);
    if (tool)
        return;

    setCMakeTool(k, defaultValue());
}

void CMakeKitInformation::fix(Kit *k)
{
    CMakeTool *tool = CMakeKitInformation::cmakeTool(k);
    if (!tool)
        setup(k);
}

KitInformation::ItemList CMakeKitInformation::toUserOutput(const Kit *k) const
{
    CMakeTool *tool = cmakeTool(k);
    return ItemList() << qMakePair(tr("CMake"), tool == 0 ? tr("Unconfigured") : tool->displayName());
}

KitConfigWidget *CMakeKitInformation::createConfigWidget(Kit *k) const
{
    return new Internal::CMakeKitConfigWidget(k, this);
}

} // namespace CMakeProjectManager
<commit_msg>CMake: Initialize kit priority<commit_after>/****************************************************************************
**
** Copyright (C) 2015 Canonical Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "cmakekitinformation.h"
#include "cmakekitconfigwidget.h"
#include "cmaketoolmanager.h"
#include "cmaketool.h"

#include <utils/qtcassert.h>
#include <projectexplorer/task.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/projectexplorerconstants.h>

#include <QDebug>

using namespace ProjectExplorer;

namespace CMakeProjectManager {

CMakeKitInformation::CMakeKitInformation()
{
    setObjectName(QLatin1String("CMakeKitInformation"));
    setId(CMakeKitInformation::id());
    setPriority(20000);

    //make sure the default value is set if a selected CMake is removed
    connect(CMakeToolManager::instance(), &CMakeToolManager::cmakeRemoved,
            [this]() { foreach (Kit *k, KitManager::kits()) fix(k); });

    //make sure the default value is set if a new default CMake is set
    connect(CMakeToolManager::instance(), &CMakeToolManager::defaultCMakeChanged,
            [this]() { foreach (Kit *k, KitManager::kits()) fix(k); });
}

Core::Id CMakeKitInformation::id()
{
    return "CMakeProjectManager.CMakeKitInformation";
}

CMakeTool *CMakeKitInformation::cmakeTool(const Kit *k)
{
    if (!k)
        return 0;

    const QVariant id = k->value(CMakeKitInformation::id());
    return CMakeToolManager::findById(Core::Id::fromSetting(id));
}

void CMakeKitInformation::setCMakeTool(Kit *k, const Core::Id id)
{
    QTC_ASSERT(k, return);

    if (id.isValid()) {
        // Only set cmake tools that are known to the manager
        QTC_ASSERT(CMakeToolManager::findById(id), return);
        k->setValue(CMakeKitInformation::id(), id.toSetting());
    } else {
        //setting a empty Core::Id will reset to the default value
        k->setValue(CMakeKitInformation::id(),defaultValue().toSetting());
    }
}

Core::Id CMakeKitInformation::defaultValue()
{
    CMakeTool *defaultTool = CMakeToolManager::defaultCMakeTool();
    if (defaultTool)
        return defaultTool->id();

    return Core::Id();
}

QVariant CMakeKitInformation::defaultValue(Kit *) const
{
    return defaultValue().toSetting();
}

QList<Task> CMakeKitInformation::validate(const Kit *k) const
{
    Q_UNUSED(k);
    return QList<Task>();
}

void CMakeKitInformation::setup(Kit *k)
{
    CMakeTool *tool = CMakeKitInformation::cmakeTool(k);
    if (tool)
        return;

    setCMakeTool(k, defaultValue());
}

void CMakeKitInformation::fix(Kit *k)
{
    CMakeTool *tool = CMakeKitInformation::cmakeTool(k);
    if (!tool)
        setup(k);
}

KitInformation::ItemList CMakeKitInformation::toUserOutput(const Kit *k) const
{
    CMakeTool *tool = cmakeTool(k);
    return ItemList() << qMakePair(tr("CMake"), tool == 0 ? tr("Unconfigured") : tool->displayName());
}

KitConfigWidget *CMakeKitInformation::createConfigWidget(Kit *k) const
{
    return new Internal::CMakeKitConfigWidget(k, this);
}

} // namespace CMakeProjectManager
<|endoftext|>


<commit_before>// TRENTO: Reduced Thickness Event-by-event Nuclear Topology
// Copyright 2015 Jonah E. Bernhard, J. Scott Moreland
// MIT License

#include "nucleon.h"

#include <cmath>
#include <limits>
#include <random>
#include <stdexcept>

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <iomanip>

#include <boost/math/constants/constants.hpp>
#include <boost/math/special_functions/expint.hpp>
#include <boost/math/tools/roots.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/math/special_functions/erf.hpp>
#include <boost/filesystem.hpp>

#include "fwd_decl.h"

namespace trento {

namespace {

// These constants define distances in terms of the width of the nucleon profile
// Gaussian thickness function.

// Truncation radius of the thickness function.
constexpr double radius_widths = 5.;

// Maximum impact parameter for participation.
constexpr double max_impact_widths = 6.;
// Create ctor parameters for unit mean std::gamma_distribution.
//   mean = alpha*beta == 1  ->  beta = 1/alpha
// Used below in NucleonProfile ctor initializer list.

template <typename RealType> using param_type =
  typename std::gamma_distribution<RealType>::param_type;

template <typename RealType>
param_type<RealType> gamma_param_unit_mean(RealType alpha = 1.) {
  return param_type<RealType>{alpha, 1./alpha};
}

// Return appropriate path to temporary file directory.
// Used to store cross section parameter \sigma_partonic.
fs::path get_data_home() {
  const auto data_path = std::getenv("XDG_DATA_HOME");
  if(data_path == nullptr)
    return fs::path{std::getenv("HOME")} / ".local/share";
  return data_path;
}

// Test approximate cross section parameter equality
bool almost_equal(double a, double b) {
  return fabs(a - b) < 1e-6;
}

// Default parton width to nucleon width.
double infer_parton_width(const VarMap& var_map) {
  auto nucleon_width = var_map["nucleon-width"].as<double>();
  auto parton_width = var_map["parton-width"].as<double>();
  if (parton_width < 0)
    return nucleon_width;
  else
    return parton_width;
}

// Determine the effective parton-parton cross section for sampling participants.
// TODO: derive this
double analytic_partonic_cross_section(const VarMap& var_map) {
  // Read parameters from the configuration.
  auto sigma_nn = var_map["cross-section"].as<double>();
  auto width = var_map["nucleon-width"].as<double>();

  // TODO: automatically set from beam energy
  // if (sigma_nn < 0.) {
  //   auto sqrt_s = var_map["beam-energy"].as<double>();
  // }

  // Initialize arguments for boost root finding function.

  // Bracket min and max.
  auto a = -10.;
  auto b = 20.;

  // Tolerance function.
  // Require 3/4 of double precision.
  math::tools::eps_tolerance<double> tol{
    (std::numeric_limits<double>::digits * 3) / 4};

  // Maximum iterations.
  // This is overkill -- in testing only 10-20 iterations were required
  // (but no harm in overestimating).
  boost::uintmax_t max_iter = 1000;

  // The right-hand side of the equation.
  auto rhs = sigma_nn / (4 * math::double_constants::pi * sqr(width));

  // This quantity appears a couple times in the equation.
  auto c = sqr(max_impact_widths) / 4;

  try {
    auto result = math::tools::toms748_solve(
      [&rhs, &c](double x) {
        using std::exp;
        using math::expint;
        return c - expint(-exp(x)) + expint(-exp(x-c)) - rhs;
      },
      a, b, tol, max_iter);

    auto cross_section_param = .5*(result.first + result.second);
    return std::exp(cross_section_param) * 4 * math::double_constants::pi * sqr(width);
  }
  catch (const std::domain_error&) {
    // Root finding fails for very small nucleon widths, w^2/sigma_nn < ~0.01.
    throw std::domain_error{
      "unable to fit cross section -- nucleon and/or parton width too small?"};
  }
}

// Use Monte Carlo methods to determine the partonic cross section
// \sigma_partonic. Solves MonteCarloCrossSection(sigma_partonic) = sigma_nn.
double numeric_partonic_cross_section(const VarMap& var_map) {
  MonteCarloCrossSection mc_cross_section(var_map);
  auto sigma_nn = var_map["cross-section"].as<double>();
  auto parton_width = infer_parton_width(var_map);

  // Bracket min and max.
  auto a = -10.;
  auto b = 20.;

  // Tolerance function.
  math::tools::eps_tolerance<double> tol{8};

  // Maximum iterations.
  boost::uintmax_t max_iter = 20;

  // Dimensional constant [fm^-1] used to rescale sigma_partonic
  auto c = 4 * math::double_constants::pi * sqr(parton_width);

  try {
    auto result = math::tools::toms748_solve(
      [&sigma_nn, &mc_cross_section, &c](double cross_section_param) {
        auto x = std::exp(cross_section_param) * c;
        return mc_cross_section(x) - sigma_nn;
      },
      a, b, tol, max_iter);

    auto cross_section_param = .5*(result.first + result.second);
    return std::exp(cross_section_param) * c;
  }
  catch (const std::domain_error&) {
    // Root finding fails for very small nucleon widths, w^2/sigma_nn < ~0.01.
    throw std::domain_error{
      "unable to fit cross section -- nucleon and/or parton width too small?"};
  }
}

// Determine the cross section parameter sigma_partonic, given the
// nucleon width, parton width, nucleon-nucleon cross section, and parton number.
double partonic_cross_section(const VarMap& var_map) {
  // Read parameters from the configuration.
  auto parton_width = infer_parton_width(var_map);
  auto nucleon_width = var_map["nucleon-width"].as<double>();
  auto sigma_nn = var_map["cross-section"].as<double>();
  auto nparton = var_map["parton-number"].as<int>();

  // Create trento cache directory
  auto cache_dir = get_data_home() / "trento";
  std::cout << "cache_dir " << cache_dir << std::endl;
  fs::create_directory(cache_dir);

  // Create dummy cross section file
  auto cache_path = cache_dir / "cross_section.dat";
  std::fstream cache_file(cache_path.string(),
      std::ios_base::out | std::ios_base::in | std::ios_base::app);

  int nparton_;
  double nucleon_width_;
  double parton_width_;
  double sigma_nn_;
  double sigma_partonic;

  // Check parameter configuration cache
  while(!cache_file.eof()) {
    cache_file >> nparton_ >> nucleon_width_ >>
      parton_width_ >> sigma_nn_ >> sigma_partonic;
    if (almost_equal(nucleon_width, nucleon_width_) &&
        almost_equal(parton_width, parton_width_) &&
        almost_equal(sigma_nn, sigma_nn_) &&
        (nparton == nparton_)) {
      return sigma_partonic;
    }
  }

  // Use a semi-analytic method to determine sigma_partonic
  // if there is no subnucleonic structure---otherwise use MC method.
  if (nucleon_width == parton_width)
    sigma_partonic = analytic_partonic_cross_section(var_map);
  else
    sigma_partonic = numeric_partonic_cross_section(var_map);

  // Save new cross section parameters to cache
  using std::fixed;
  using std::setprecision;
  using std::setw;
  using std::scientific;

  cache_file.clear();
  cache_file.seekg(0, std::ios::end);

  if (cache_file.tellg() != 0) {
    cache_file << std::endl;
  }

  cache_file.clear();

  cache_file << setprecision(6) << std::left
             << setw(8) << fixed << nparton
             << setw(10) << fixed << nucleon_width
             << setw(10) << fixed << parton_width
             << setw(10) << fixed << sigma_nn
             << setw(14) << scientific << sigma_partonic;

  return sigma_partonic;
}

// Determine the width of the normal distribution for sampling parton positions.
double compute_parton_sampling_width(const VarMap& var_map) {
  // Read parameters from the configuration.
  auto nucleon_width = var_map["nucleon-width"].as<double>();
  auto parton_width = var_map["parton-width"].as<double>();

  // Default parton width to nucleon width.
  if (parton_width < 0) return 0.;

  // Compute Gaussian sampling width by deconvolving the parton profile from the
  // nucleon profile.  The convolution of two Gaussians is a third Gaussian
  // with the variances simply added together.
  auto sampling_width_sq = sqr(nucleon_width) - sqr(parton_width);
  auto TINY = 1e-8;

  if (sampling_width_sq < -TINY) {
    throw std::out_of_range{
      "the parton width cannot be larger than the nucleon width"};
  }

  return std::sqrt(std::max(sampling_width_sq, 0.));
}

}  // unnamed namespace

NucleonCommon::NucleonCommon(const VarMap& var_map)
    : fast_exp_(-.5*sqr(radius_widths), 0., 1000),
      max_impact_sq_(sqr(max_impact_widths*var_map["nucleon-width"].as<double>())),
      parton_width_sq_(sqr(infer_parton_width(var_map))),
      parton_radius_sq_(sqr(radius_widths)*parton_width_sq_),
      npartons_(std::size_t(var_map["parton-number"].as<int>())),
      sigma_partonic_(partonic_cross_section(var_map)),
      prefactor_(math::double_constants::one_div_two_pi/parton_width_sq_/npartons_),
      participant_fluctuation_dist_(gamma_param_unit_mean(var_map["fluctuation"].as<double>())),
      parton_position_dist_(0, compute_parton_sampling_width(var_map))
{}

MonteCarloCrossSection::MonteCarloCrossSection(const VarMap& var_map)
  : npartons(std::size_t(var_map["parton-number"].as<int>())),
    nucleon_width(var_map["nucleon-width"].as<double>()),
    parton_width(infer_parton_width(var_map)),
    parton_sampling_width(compute_parton_sampling_width(var_map)),
    parton_width_sq(sqr(parton_width)),
    prefactor(math::double_constants::one_div_two_pi/parton_width_sq/npartons)
{}

double MonteCarloCrossSection::operator() (const double sigma_partonic) const {

  random::CyclicNormal<> cyclic_normal{
    0., parton_sampling_width, cache_size, n_loops
  };

  struct Parton {
    double x, y;
  };

  std::vector<Parton> nucleonA(npartons);
  std::vector<Parton> nucleonB(npartons);

  auto bmax = max_impact_widths * nucleon_width;
  auto arg_max = 0.25*sqr(bmax)/parton_width_sq;
  const FastExp<double> fast_exp(-arg_max, 0., 1000);

  double ref_cross_section = 0.;
  double prob_miss = 0.;
  int pass_tolerance = 0;

  for (std::size_t n = 0; n < n_max; ++n) {
    // Sample b from P(b)db = 2*pi*b.
    auto b = bmax * std::sqrt(random::canonical<double>());

    for (auto&& p : nucleonA) {
      p.x = cyclic_normal(random::engine);
      p.y = cyclic_normal(random::engine);
    }

    for (auto&& p : nucleonB) {
      p.x = cyclic_normal(random::engine);
      p.y = cyclic_normal(random::engine);
    }

    auto overlap = 0.;
    for (auto&& pa : nucleonA) {
      for (auto&& pb : nucleonB) {
        auto distance_sq = sqr(pa.x - pb.x + b) + sqr(pa.y - pb.y);
        auto arg = .25*distance_sq/parton_width_sq;
        if (arg < arg_max) overlap += fast_exp(-arg);
      }
    }

    prob_miss +=
      std::exp(-sigma_partonic * prefactor/(2.*npartons) * overlap);

    auto fraction_hit = 1. - (prob_miss/n);
    auto sample_area = math::double_constants::pi * sqr(bmax);
    auto cross_section = fraction_hit * sample_area;

    auto update_difference =
      std::abs((cross_section - ref_cross_section)/cross_section);

    if (update_difference < tolerance) {
      ++pass_tolerance;
    } else {
      pass_tolerance = 0;
      ref_cross_section = cross_section;
    }

    if (pass_tolerance > n_pass){
      return cross_section;
    }
  }

  throw std::out_of_range{
    "Partonic cross section failed to converge \
      -- check nucleon-width, parton-width and npartons"};

  // Code throws an error before it ever gets here.
  return -1;
}

}  // namespace trento
<commit_msg>Remove cout of cache_dir<commit_after>// TRENTO: Reduced Thickness Event-by-event Nuclear Topology
// Copyright 2015 Jonah E. Bernhard, J. Scott Moreland
// MIT License

#include "nucleon.h"

#include <cmath>
#include <limits>
#include <random>
#include <stdexcept>

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <iomanip>

#include <boost/math/constants/constants.hpp>
#include <boost/math/special_functions/expint.hpp>
#include <boost/math/tools/roots.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/math/special_functions/erf.hpp>
#include <boost/filesystem.hpp>

#include "fwd_decl.h"

namespace trento {

namespace {

// These constants define distances in terms of the width of the nucleon profile
// Gaussian thickness function.

// Truncation radius of the thickness function.
constexpr double radius_widths = 5.;

// Maximum impact parameter for participation.
constexpr double max_impact_widths = 6.;
// Create ctor parameters for unit mean std::gamma_distribution.
//   mean = alpha*beta == 1  ->  beta = 1/alpha
// Used below in NucleonProfile ctor initializer list.

template <typename RealType> using param_type =
  typename std::gamma_distribution<RealType>::param_type;

template <typename RealType>
param_type<RealType> gamma_param_unit_mean(RealType alpha = 1.) {
  return param_type<RealType>{alpha, 1./alpha};
}

// Return appropriate path to temporary file directory.
// Used to store cross section parameter \sigma_partonic.
fs::path get_data_home() {
  const auto data_path = std::getenv("XDG_DATA_HOME");
  if(data_path == nullptr)
    return fs::path{std::getenv("HOME")} / ".local/share";
  return data_path;
}

// Test approximate cross section parameter equality
bool almost_equal(double a, double b) {
  return fabs(a - b) < 1e-6;
}

// Default parton width to nucleon width.
double infer_parton_width(const VarMap& var_map) {
  auto nucleon_width = var_map["nucleon-width"].as<double>();
  auto parton_width = var_map["parton-width"].as<double>();
  if (parton_width < 0)
    return nucleon_width;
  else
    return parton_width;
}

// Determine the effective parton-parton cross section for sampling participants.
// TODO: derive this
double analytic_partonic_cross_section(const VarMap& var_map) {
  // Read parameters from the configuration.
  auto sigma_nn = var_map["cross-section"].as<double>();
  auto width = var_map["nucleon-width"].as<double>();

  // TODO: automatically set from beam energy
  // if (sigma_nn < 0.) {
  //   auto sqrt_s = var_map["beam-energy"].as<double>();
  // }

  // Initialize arguments for boost root finding function.

  // Bracket min and max.
  auto a = -10.;
  auto b = 20.;

  // Tolerance function.
  // Require 3/4 of double precision.
  math::tools::eps_tolerance<double> tol{
    (std::numeric_limits<double>::digits * 3) / 4};

  // Maximum iterations.
  // This is overkill -- in testing only 10-20 iterations were required
  // (but no harm in overestimating).
  boost::uintmax_t max_iter = 1000;

  // The right-hand side of the equation.
  auto rhs = sigma_nn / (4 * math::double_constants::pi * sqr(width));

  // This quantity appears a couple times in the equation.
  auto c = sqr(max_impact_widths) / 4;

  try {
    auto result = math::tools::toms748_solve(
      [&rhs, &c](double x) {
        using std::exp;
        using math::expint;
        return c - expint(-exp(x)) + expint(-exp(x-c)) - rhs;
      },
      a, b, tol, max_iter);

    auto cross_section_param = .5*(result.first + result.second);
    return std::exp(cross_section_param) * 4 * math::double_constants::pi * sqr(width);
  }
  catch (const std::domain_error&) {
    // Root finding fails for very small nucleon widths, w^2/sigma_nn < ~0.01.
    throw std::domain_error{
      "unable to fit cross section -- nucleon and/or parton width too small?"};
  }
}

// Use Monte Carlo methods to determine the partonic cross section
// \sigma_partonic. Solves MonteCarloCrossSection(sigma_partonic) = sigma_nn.
double numeric_partonic_cross_section(const VarMap& var_map) {
  MonteCarloCrossSection mc_cross_section(var_map);
  auto sigma_nn = var_map["cross-section"].as<double>();
  auto parton_width = infer_parton_width(var_map);

  // Bracket min and max.
  auto a = -10.;
  auto b = 20.;

  // Tolerance function.
  math::tools::eps_tolerance<double> tol{8};

  // Maximum iterations.
  boost::uintmax_t max_iter = 20;

  // Dimensional constant [fm^-1] used to rescale sigma_partonic
  auto c = 4 * math::double_constants::pi * sqr(parton_width);

  try {
    auto result = math::tools::toms748_solve(
      [&sigma_nn, &mc_cross_section, &c](double cross_section_param) {
        auto x = std::exp(cross_section_param) * c;
        return mc_cross_section(x) - sigma_nn;
      },
      a, b, tol, max_iter);

    auto cross_section_param = .5*(result.first + result.second);
    return std::exp(cross_section_param) * c;
  }
  catch (const std::domain_error&) {
    // Root finding fails for very small nucleon widths, w^2/sigma_nn < ~0.01.
    throw std::domain_error{
      "unable to fit cross section -- nucleon and/or parton width too small?"};
  }
}

// Determine the cross section parameter sigma_partonic, given the
// nucleon width, parton width, nucleon-nucleon cross section, and parton number.
double partonic_cross_section(const VarMap& var_map) {
  // Read parameters from the configuration.
  auto parton_width = infer_parton_width(var_map);
  auto nucleon_width = var_map["nucleon-width"].as<double>();
  auto sigma_nn = var_map["cross-section"].as<double>();
  auto nparton = var_map["parton-number"].as<int>();

  // Create trento cache directory
  auto cache_dir = get_data_home() / "trento";
  fs::create_directory(cache_dir);

  // Create dummy cross section file
  auto cache_path = cache_dir / "cross_section.dat";
  std::fstream cache_file(cache_path.string(),
      std::ios_base::out | std::ios_base::in | std::ios_base::app);

  int nparton_;
  double nucleon_width_;
  double parton_width_;
  double sigma_nn_;
  double sigma_partonic;

  // Check parameter configuration cache
  while(!cache_file.eof()) {
    cache_file >> nparton_ >> nucleon_width_ >>
      parton_width_ >> sigma_nn_ >> sigma_partonic;
    if (almost_equal(nucleon_width, nucleon_width_) &&
        almost_equal(parton_width, parton_width_) &&
        almost_equal(sigma_nn, sigma_nn_) &&
        (nparton == nparton_)) {
      return sigma_partonic;
    }
  }

  // Use a semi-analytic method to determine sigma_partonic
  // if there is no subnucleonic structure---otherwise use MC method.
  if (nucleon_width == parton_width)
    sigma_partonic = analytic_partonic_cross_section(var_map);
  else
    sigma_partonic = numeric_partonic_cross_section(var_map);

  // Save new cross section parameters to cache
  using std::fixed;
  using std::setprecision;
  using std::setw;
  using std::scientific;

  cache_file.clear();
  cache_file.seekg(0, std::ios::end);

  if (cache_file.tellg() != 0) {
    cache_file << std::endl;
  }

  cache_file.clear();

  cache_file << setprecision(6) << std::left
             << setw(8) << fixed << nparton
             << setw(10) << fixed << nucleon_width
             << setw(10) << fixed << parton_width
             << setw(10) << fixed << sigma_nn
             << setw(14) << scientific << sigma_partonic;

  return sigma_partonic;
}

// Determine the width of the normal distribution for sampling parton positions.
double compute_parton_sampling_width(const VarMap& var_map) {
  // Read parameters from the configuration.
  auto nucleon_width = var_map["nucleon-width"].as<double>();
  auto parton_width = var_map["parton-width"].as<double>();

  // Default parton width to nucleon width.
  if (parton_width < 0) return 0.;

  // Compute Gaussian sampling width by deconvolving the parton profile from the
  // nucleon profile.  The convolution of two Gaussians is a third Gaussian
  // with the variances simply added together.
  auto sampling_width_sq = sqr(nucleon_width) - sqr(parton_width);
  auto TINY = 1e-8;

  if (sampling_width_sq < -TINY) {
    throw std::out_of_range{
      "the parton width cannot be larger than the nucleon width"};
  }

  return std::sqrt(std::max(sampling_width_sq, 0.));
}

}  // unnamed namespace

NucleonCommon::NucleonCommon(const VarMap& var_map)
    : fast_exp_(-.5*sqr(radius_widths), 0., 1000),
      max_impact_sq_(sqr(max_impact_widths*var_map["nucleon-width"].as<double>())),
      parton_width_sq_(sqr(infer_parton_width(var_map))),
      parton_radius_sq_(sqr(radius_widths)*parton_width_sq_),
      npartons_(std::size_t(var_map["parton-number"].as<int>())),
      sigma_partonic_(partonic_cross_section(var_map)),
      prefactor_(math::double_constants::one_div_two_pi/parton_width_sq_/npartons_),
      participant_fluctuation_dist_(gamma_param_unit_mean(var_map["fluctuation"].as<double>())),
      parton_position_dist_(0, compute_parton_sampling_width(var_map))
{}

MonteCarloCrossSection::MonteCarloCrossSection(const VarMap& var_map)
  : npartons(std::size_t(var_map["parton-number"].as<int>())),
    nucleon_width(var_map["nucleon-width"].as<double>()),
    parton_width(infer_parton_width(var_map)),
    parton_sampling_width(compute_parton_sampling_width(var_map)),
    parton_width_sq(sqr(parton_width)),
    prefactor(math::double_constants::one_div_two_pi/parton_width_sq/npartons)
{}

double MonteCarloCrossSection::operator() (const double sigma_partonic) const {

  random::CyclicNormal<> cyclic_normal{
    0., parton_sampling_width, cache_size, n_loops
  };

  struct Parton {
    double x, y;
  };

  std::vector<Parton> nucleonA(npartons);
  std::vector<Parton> nucleonB(npartons);

  auto bmax = max_impact_widths * nucleon_width;
  auto arg_max = 0.25*sqr(bmax)/parton_width_sq;
  const FastExp<double> fast_exp(-arg_max, 0., 1000);

  double ref_cross_section = 0.;
  double prob_miss = 0.;
  int pass_tolerance = 0;

  for (std::size_t n = 0; n < n_max; ++n) {
    // Sample b from P(b)db = 2*pi*b.
    auto b = bmax * std::sqrt(random::canonical<double>());

    for (auto&& p : nucleonA) {
      p.x = cyclic_normal(random::engine);
      p.y = cyclic_normal(random::engine);
    }

    for (auto&& p : nucleonB) {
      p.x = cyclic_normal(random::engine);
      p.y = cyclic_normal(random::engine);
    }

    auto overlap = 0.;
    for (auto&& pa : nucleonA) {
      for (auto&& pb : nucleonB) {
        auto distance_sq = sqr(pa.x - pb.x + b) + sqr(pa.y - pb.y);
        auto arg = .25*distance_sq/parton_width_sq;
        if (arg < arg_max) overlap += fast_exp(-arg);
      }
    }

    prob_miss +=
      std::exp(-sigma_partonic * prefactor/(2.*npartons) * overlap);

    auto fraction_hit = 1. - (prob_miss/n);
    auto sample_area = math::double_constants::pi * sqr(bmax);
    auto cross_section = fraction_hit * sample_area;

    auto update_difference =
      std::abs((cross_section - ref_cross_section)/cross_section);

    if (update_difference < tolerance) {
      ++pass_tolerance;
    } else {
      pass_tolerance = 0;
      ref_cross_section = cross_section;
    }

    if (pass_tolerance > n_pass){
      return cross_section;
    }
  }

  throw std::out_of_range{
    "Partonic cross section failed to converge \
      -- check nucleon-width, parton-width and npartons"};

  // Code throws an error before it ever gets here.
  return -1;
}

}  // namespace trento
<|endoftext|>


<commit_before>// http_client_test.cpp : ̨Ӧóڵ㡣
//

#include "HttpClient.h"
#include <tchar.h>
#include <thread>
#include <mutex>
#include "jansson.h"
using namespace  network;

static std::mutex       s_post_mutex;
#ifndef __CLOUD_BOX
//#define __CLOUD_BOX
#endif //__CLOUD_BOX

#ifdef __CLOUD_BOX
#define HTTP_URL		"http://117.121.32.94:20000/"
#else
#define HTTP_URL		"http://192.168.22.61:3000/"
#endif // __CLOUD_BOX

class HttpClientTest : public Ref
{
public:
	HttpClientTest() {}

	~HttpClientTest(){}

	void initThread();

	void postThread();
	//	test http_server,http component for login
	void post1();

	void post2();

	//	test for mail
	void post3();

	//Http Response Callback
	void onHttpRequestCompleted(network::HttpClient *sender, network::HttpResponse *response);

};

void HttpClientTest::post1()
{
	if(0)
	{
		HttpRequest* request = new HttpRequest();
		request->setUrl("http://httpbin.org/post");
		request->setRequestType(HttpRequest::Type::POST);
		request->setResponseCallback(this, httpresponse_selector(HttpClientTest::onHttpRequestCompleted));

		// write the post data
		char postData[22] = "binary=hello\0\0cocos2d";  // including \0, the strings after \0 should not be cut in response
		request->setRequestData(postData, 22);

		request->setTag("POST Binary test");
		HttpClient::getInstance()->send(request);
		request->release();
	}
	else
	{
		try
		{
			s_post_mutex.lock();
			//	post data to http server
			std::string __string_account = "&account=king_lee";
			std::string __string_msg = "msg=";
			json_t* __msg = json_object();
			json_t* __msg_id = json_integer(/*MSG_ID::MSG_LOGIN*/2);
			json_t* __msg_context = json_string("context");
			json_object_set(__msg, "msg_id", __msg_id);
			json_object_set(__msg, "context", __msg_context);

			HttpRequest* request = new HttpRequest();
			request->setUrl("http://192.168.22.61:3001/");
			std::vector<std::string> __head;
			__head.push_back("Content-Type: application/json; charset=utf-8");
			request->setHeaders(__head);
			request->setRequestType(HttpRequest::Type::POST);
			request->setResponseCallback(this, httpresponse_selector(HttpClientTest::onHttpRequestCompleted));

			// write the post data
			const char* postData = json_dumps(__msg,0);
			if(postData)
			{
				//	msg={"context": "context", "msg_id": 2}
				__string_msg  += postData;
				__string_msg += __string_account;
				request->setRequestData(__string_msg.c_str(), __string_msg.length());
			}
			request->setTag("POST test1\n");
			HttpClient::getInstance()->send(request);
			request->release();

			// decref for json object
			json_decref(__msg_id);
			s_post_mutex.unlock();
		}
		catch(std::exception & __exception)
		{
			printf("exception : %s\n",__exception.what());
			s_post_mutex.unlock();
		}
	}
}

void HttpClientTest::post2()
{
	//	post data to http server
	std::string __string_token = "&token=1234567788";
	std::string __string_msg = "msg=";
	json_t* __msg = json_object();
	json_t* __msg_id = json_integer(/*TYPE_MSG_GET_SRV_TIME:*/3);
	json_t* __flow_id = json_integer(88888888);
	json_object_set(__msg, "msg_id", __msg_id);
	json_object_set(__msg, "flowid", __flow_id);

	HttpRequest* request = new HttpRequest();
	request->setUrl(HTTP_URL);
	request->setRequestType(HttpRequest::Type::POST);
	request->setResponseCallback(this, httpresponse_selector(HttpClientTest::onHttpRequestCompleted));

	// write the post data
	const char* postData = json_dumps(__msg,0);
	if(postData)
	{
		__string_msg  += postData;
		__string_msg += __string_token;
		request->setRequestData(__string_msg.c_str(), __string_msg.length());
	}
	request->setTag("POST test1\n");
	HttpClient::getInstance()->send(request);
	request->release();

	// decref for json object
	json_decref(__msg_id);
	json_decref(__flow_id);
}

void HttpClientTest::post3()
{
	//	post data to http server
	std::string __string_token = "&token=1234567788";
	std::string __string_msg = "msg=";
	json_t* __msg = json_object();
	json_t* __msg_id = json_integer(/*TYPE_MSG_MAIL:*/4);
	json_t* __msg_title = json_string("title");
	json_t* __msg_content = json_string("content");
	json_t* __msg_channel = json_string("qihu360");
	json_t* __msg_version = json_string("1.1.1.0");
	json_object_set(__msg, "msg_id", __msg_id);
	json_object_set(__msg, "title", __msg_title);
	json_object_set(__msg, "content", __msg_content);
	json_object_set(__msg, "channel", __msg_channel);
	json_object_set(__msg, "version", __msg_version);

	HttpRequest* request = new HttpRequest();
	request->setUrl(HTTP_URL);
	request->setRequestType(HttpRequest::Type::POST);
	request->setResponseCallback(this, httpresponse_selector(HttpClientTest::onHttpRequestCompleted));

	// write the post data
	const char* postData = json_dumps(__msg,0);
	if(postData)
	{
		__string_msg  += postData;
		__string_msg += __string_token;
		request->setRequestData(__string_msg.c_str(), __string_msg.length());
	}
	request->setTag("POST test1\n");
	HttpClient::getInstance()->send(request);
	request->release();

	// decref for json object
	json_decref(__msg_id);
}

void HttpClientTest::onHttpRequestCompleted( network::HttpClient *sender, network::HttpResponse *response )
{
	if (!response)
	{
		return;
	}

	// You can get original request type from: response->request->reqType
	if (0 != strlen(response->getHttpRequest()->getTag()))
	{
		printf("%s completed ", response->getHttpRequest()->getTag());
	}

	long statusCode = response->getResponseCode();
	char statusString[64] = {};
	sprintf(statusString, "HTTP Status Code: %ld, tag = %s", statusCode, response->getHttpRequest()->getTag());
	printf("response code: %ld", statusCode);

	if (!response->isSucceed())
	{
		printf("response failed");
		printf("error buffer: %s", response->getErrorBuffer());
		return;
	}

	// dump data
	std::vector<char> *buffer = response->getResponseData();
	printf("Http Test, dump data: \n");
	for (unsigned int i = 0; i < buffer->size(); i++)
	{
		printf("%c", (*buffer)[i]);
	}
	printf("\n");
}

void HttpClientTest::postThread()
{
	while (true)
	{
		this->post1();
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
	}
}

void HttpClientTest::initThread()
{
	const int __max_thread = 1;
	for(int i = 0; i < __max_thread; ++i)
	{
		auto t = std::thread(std::bind(&HttpClientTest::postThread,this));
		t.detach();
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	HttpClientTest* __test = new HttpClientTest();
	if(1)
	{
		if(0)
		{
			__test->post1();
		}
		else
		{
			__test->post2();
			__test->post3();
		}

	}
	else
	{
		__test->initThread();
	}

	while (true)
	{
		if(1)
		{
			::_sleep(1);
		}
		else
		{
			std::this_thread::sleep_for(std::chrono::milliseconds(1));
		}
	}
	return 0;
}

<commit_msg>add activity test<commit_after>// http_client_test.cpp : ̨Ӧóڵ㡣
//

#include "HttpClient.h"
#include <tchar.h>
#include <thread>
#include <mutex>
#include "jansson.h"
using namespace  network;

static std::mutex       s_post_mutex;
#ifndef __CLOUD_BOX
//#define __CLOUD_BOX
#endif //__CLOUD_BOX

#ifndef __CLOUD_BOX_FORMAL
#define __CLOUD_BOX_FORMAL
#endif //__CLOUD_BOX_FORMAL

#ifdef __CLOUD_BOX
	#ifdef __CLOUD_BOX_FORMAL
	#define HTTP_URL		"server.wscs.appget.cn:20000/"
	#else
	#define HTTP_URL		"http://117.121.32.94:20000/"
	#endif //__CLOUD_BOX_FORMAL
#else
#define HTTP_URL		"http://192.168.22.61:20000/"
#endif // __CLOUD_BOX

class HttpClientTest : public Ref
{
public:
	HttpClientTest() {}

	~HttpClientTest(){}

	void initThread();

	void postThread();
	//	test http_server,http component for login
	void post1();

	void post2();

	//	test for mail
	void post3();

	void post4(int __msg_type);

	//Http Response Callback
	void onHttpRequestCompleted(network::HttpClient *sender, network::HttpResponse *response);

};

void HttpClientTest::post1()
{
	if(0)
	{
		HttpRequest* request = new HttpRequest();
		request->setUrl("http://httpbin.org/post");
		request->setRequestType(HttpRequest::Type::POST);
		request->setResponseCallback(this, httpresponse_selector(HttpClientTest::onHttpRequestCompleted));

		// write the post data
		char postData[22] = "binary=hello\0\0cocos2d";  // including \0, the strings after \0 should not be cut in response
		request->setRequestData(postData, 22);

		request->setTag("POST Binary test");
		HttpClient::getInstance()->send(request);
		request->release();
	}
	else
	{
		try
		{
			s_post_mutex.lock();
			//	post data to http server
			std::string __string_account = "&account=king_lee";
			std::string __string_msg = "msg=";
			json_t* __msg = json_object();
			json_t* __msg_id = json_integer(/*MSG_ID::MSG_LOGIN*/2);
			json_t* __msg_context = json_string("context");
			json_object_set(__msg, "msg_id", __msg_id);
			json_object_set(__msg, "context", __msg_context);

			HttpRequest* request = new HttpRequest();
			request->setUrl("http://192.168.22.61:3001/");
			std::vector<std::string> __head;
			__head.push_back("Content-Type: application/json; charset=utf-8");
			request->setHeaders(__head);
			request->setRequestType(HttpRequest::Type::POST);
			request->setResponseCallback(this, httpresponse_selector(HttpClientTest::onHttpRequestCompleted));

			// write the post data
			const char* postData = json_dumps(__msg,0);
			if(postData)
			{
				//	msg={"context": "context", "msg_id": 2}
				__string_msg  += postData;
				__string_msg += __string_account;
				request->setRequestData(__string_msg.c_str(), __string_msg.length());
			}
			request->setTag("POST test1\n");
			HttpClient::getInstance()->send(request);
			request->release();

			// decref for json object
			json_decref(__msg_id);
			s_post_mutex.unlock();
		}
		catch(std::exception & __exception)
		{
			printf("exception : %s\n",__exception.what());
			s_post_mutex.unlock();
		}
	}
}

void HttpClientTest::post2()
{
	//	post data to http server
	std::string __string_token = "&token=1234567788";
	std::string __string_msg = "msg=";
	json_t* __msg = json_object();
	json_t* __msg_id = json_integer(/*TYPE_MSG_GET_SRV_TIME:*/3);
	json_t* __flow_id = json_integer(88888888);
	json_object_set(__msg, "msg_id", __msg_id);
	json_object_set(__msg, "flowid", __flow_id);

	HttpRequest* request = new HttpRequest();
	request->setUrl(HTTP_URL);
	request->setRequestType(HttpRequest::Type::POST);
	request->setResponseCallback(this, httpresponse_selector(HttpClientTest::onHttpRequestCompleted));

	// write the post data
	const char* postData = json_dumps(__msg,0);
	if(postData)
	{
		__string_msg  += postData;
		__string_msg += __string_token;
		request->setRequestData(__string_msg.c_str(), __string_msg.length());
	}
	request->setTag("POST test1\n");
	HttpClient::getInstance()->send(request);
	request->release();

	// decref for json object
	json_decref(__msg_id);
	json_decref(__flow_id);
}

void HttpClientTest::post3()
{
	//	post data to http server
	std::string __string_token = "&token=1234567788";
	std::string __string_msg = "msg=";
	json_t* __msg = json_object();
	json_t* __msg_id = json_integer(/*TYPE_MSG_MAIL:*/4);
	json_t* __msg_title = json_string("title");
	json_t* __msg_content = json_string("content");
	json_t* __msg_channel = json_string("qihu360");
	json_t* __msg_version = json_string("1.1.1.0");
	json_object_set(__msg, "msg_id", __msg_id);
	json_object_set(__msg, "title", __msg_title);
	json_object_set(__msg, "content", __msg_content);
	json_object_set(__msg, "channel", __msg_channel);
	json_object_set(__msg, "version", __msg_version);

	HttpRequest* request = new HttpRequest();
	request->setUrl(HTTP_URL);
	request->setRequestType(HttpRequest::Type::POST);
	request->setResponseCallback(this, httpresponse_selector(HttpClientTest::onHttpRequestCompleted));

	// write the post data
	const char* postData = json_dumps(__msg,0);
	if(postData)
	{
		__string_msg  += postData;
		__string_msg += __string_token;
		request->setRequestData(__string_msg.c_str(), __string_msg.length());
	}
	request->setTag("POST test1\n");
	HttpClient::getInstance()->send(request);
	request->release();

	// decref for json object
	json_decref(__msg_id);
}

void HttpClientTest::post4(int __msg_type)
{
	//	post data to http server
	std::string __string_token = "&token=1234567788";
	std::string __string_msg = "msg=";
	json_t* __msg = json_object();
	json_t* __msg_id = json_integer(__msg_type);
	json_t* __msg_channel = json_string("qihu360");
	json_t* __msg_version = json_string("1.1.1.0");
	json_object_set(__msg, "msg_id", __msg_id);
	json_object_set(__msg, "channel", __msg_channel);
	json_object_set(__msg, "version", __msg_version);

	HttpRequest* request = new HttpRequest();
	request->setUrl(HTTP_URL);
	request->setRequestType(HttpRequest::Type::POST);
	request->setResponseCallback(this, httpresponse_selector(HttpClientTest::onHttpRequestCompleted));

	// write the post data
	const char* postData = json_dumps(__msg,0);
	if(postData)
	{
		__string_msg  += postData;
		__string_msg += __string_token;
		request->setRequestData(__string_msg.c_str(), __string_msg.length());
	}
	request->setTag("POST test1\n");
	HttpClient::getInstance()->send(request);
	request->release();

	// decref for json object
	json_decref(__msg_id);
}

void HttpClientTest::onHttpRequestCompleted( network::HttpClient *sender, network::HttpResponse *response )
{
	if (!response)
	{
		return;
	}

	// You can get original request type from: response->request->reqType
	if (0 != strlen(response->getHttpRequest()->getTag()))
	{
		printf("%s completed ", response->getHttpRequest()->getTag());
	}

	long statusCode = response->getResponseCode();
	char statusString[64] = {};
	sprintf(statusString, "HTTP Status Code: %ld, tag = %s", statusCode, response->getHttpRequest()->getTag());
	printf("response code: %ld", statusCode);

	if (!response->isSucceed())
	{
		printf("response failed");
		printf("error buffer: %s", response->getErrorBuffer());
		return;
	}

	// dump data
	std::vector<char> *buffer = response->getResponseData();
	printf("Http Test, dump data: \n");
	for (unsigned int i = 0; i < buffer->size(); i++)
	{
		printf("%c", (*buffer)[i]);
	}
	printf("\n");
}

void HttpClientTest::postThread()
{
	while (true)
	{
		this->post1();
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
	}
}

void HttpClientTest::initThread()
{
	const int __max_thread = 1;
	for(int i = 0; i < __max_thread; ++i)
	{
		auto t = std::thread(std::bind(&HttpClientTest::postThread,this));
		t.detach();
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	HttpClientTest* __test = new HttpClientTest();
	if(1)
	{
		if(0)
		{
			__test->post1();
		}
		else
		{
			__test->post2();
			__test->post3();
			__test->post4(5);
			__test->post4(6);
		}

	}
	else
	{
		__test->initThread();
	}

	while (true)
	{
		if(1)
		{
			::_sleep(1);
		}
		else
		{
			std::this_thread::sleep_for(std::chrono::milliseconds(1));
		}
	}
	return 0;
}

<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011-2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "mixer_factory.hpp"

#include <string>
#include "jubatus/util/lang/shared_ptr.h"

#ifdef HAVE_ZOOKEEPER_H
#include "linear_mixer.hpp"
#include "random_mixer.hpp"
#include "broadcast_mixer.hpp"
#include "skip_mixer.hpp"
#else
#include "dummy_mixer.hpp"
#endif

namespace jubatus {
namespace server {
namespace framework {
namespace mixer {

mixer* create_mixer(
    const server_argv& a,
    const jubatus::util::lang::shared_ptr<common::lock_service>& zk) {
#ifdef HAVE_ZOOKEEPER_H
  const std::string& use_mixer = a.mixer;
  if (use_mixer == "linear_mixer") {
    return new linear_mixer(
        linear_communication::create(
            zk, a.type, a.name, a.interconnect_timeout),
        a.interval_count, a.interval_sec);
  } else if (use_mixer == "random_mixer") {
    return new random_mixer(
        push_communication::create(
            zk, a.type, a.name, a.interconnect_timeout),
        a.interval_count, a.interval_sec, std::make_pair(a.eth, a.port));
  } else if (use_mixer == "broadcast_mixer") {
    return new broadcast_mixer(
        push_communication::create(zk, a.type, a.name, a.interconnect_timeout),
        a.interval_count, a.interval_sec, std::make_pair(a.eth, a.port));
  } else if (use_mixer == "skip_mixer") {
    return new skip_mixer(
        push_communication::create(zk, a.type, a.name, a.interconnect_timeout),
        a.interval_count, a.interval_sec, std::make_pair(a.eth, a.port));
  } else {
    // TODO(beam2d): fix to throw
    return new linear_mixer(
        linear_communication::create(
            zk, a.type, a.name, a.interconnect_timeout),
        a.interval_count, a.interval_sec);
  }
#else
  return new dummy_mixer;
#endif
}

}  // namespace mixer
}  // namespace framework
}  // namespace server
}  // namespace jubatus
<commit_msg>Raise exception if unsupported mix strategy name specified<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011-2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "mixer_factory.hpp"

#include <string>
#include "jubatus/util/lang/shared_ptr.h"
#include "jubatus/core/common/exception.hpp"

#ifdef HAVE_ZOOKEEPER_H
#include "linear_mixer.hpp"
#include "random_mixer.hpp"
#include "broadcast_mixer.hpp"
#include "skip_mixer.hpp"
#else
#include "dummy_mixer.hpp"
#endif

namespace jubatus {
namespace server {
namespace framework {
namespace mixer {

mixer* create_mixer(
    const server_argv& a,
    const jubatus::util::lang::shared_ptr<common::lock_service>& zk) {
#ifdef HAVE_ZOOKEEPER_H
  const std::string& use_mixer = a.mixer;
  if (use_mixer.empty() || use_mixer == "linear_mixer") {
    return new linear_mixer(
        linear_communication::create(
            zk, a.type, a.name, a.interconnect_timeout),
        a.interval_count, a.interval_sec);
  } else if (use_mixer == "random_mixer") {
    return new random_mixer(
        push_communication::create(
            zk, a.type, a.name, a.interconnect_timeout),
        a.interval_count, a.interval_sec, std::make_pair(a.eth, a.port));
  } else if (use_mixer == "broadcast_mixer") {
    return new broadcast_mixer(
        push_communication::create(zk, a.type, a.name, a.interconnect_timeout),
        a.interval_count, a.interval_sec, std::make_pair(a.eth, a.port));
  } else if (use_mixer == "skip_mixer") {
    return new skip_mixer(
        push_communication::create(zk, a.type, a.name, a.interconnect_timeout),
        a.interval_count, a.interval_sec, std::make_pair(a.eth, a.port));
  } else {
    throw JUBATUS_EXCEPTION(jubatus::core::common::exception::runtime_error(
          "unsupported mix type (" + use_mixer + ")"));
  }
#else
  return new dummy_mixer;
#endif
}

}  // namespace mixer
}  // namespace framework
}  // namespace server
}  // namespace jubatus
<|endoftext|>


<commit_before>/* Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 *
 * Copyright 2018 INRIA.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/
/*! \file
  Fricton-Contact Non-Smooth Problem
*/
#ifndef GENERICMECHANICAL_H
#define GENERICMECHANICAL_H

#include "LinearOSNS.hpp"
#include "SiconosNumerics.h"
#include "Friction_cst.h" // from numerics, for solver id

TYPEDEF_SPTR(GenericMechanicalProblem)

/** Formalization and Resolution of a generic mechanical problem: It mixes bilateral equality, complementarity, impact and friction problems.
 *
 * This class is devoted to contains of a set of Non-Smooth Problem.
 *
 * \b Main functions:
 *  - formalization of the problem: computes M,q using the set of "active" Interactions from the simulation and \n
 *  the interactionBlock-matrices saved in the field interactionBlocks.\n
 *  Functions: initialize(), computeInteractionBlock(), preCompute()
 *  - solving of the GenericMechanical problem: function compute(), used to call solvers from Numerics through \n
 * the gmp_driver() interface of Numerics.
 *  - post-treatment of data: set values of y/lambda variables of the active Interaction (ie Interactions) using \n
 *  ouput results from the solver (velocity,reaction); function postCompute().
 *
 */
class GenericMechanical : public LinearOSNS
{
protected:
  /** serialization hooks */
  ACCEPT_SERIALIZATION(GenericMechanical);

  GenericMechanicalProblem * _pnumerics_GMP;

public:

  /** constructor from solver id
      \param numericsSolverId id of the internal friction solver of the generic problem
      default = SICONOS_FRICTION_3D_ONECONTACT_QUARTIC
   */
  GenericMechanical(int FC3D_Solver_Id = SICONOS_FRICTION_3D_ONECONTACT_QUARTIC);

  /** constructor from a pre-defined solver options set.
      \param options, the options set,
      \rst
      see :ref:`problems_and_solvers` for details.
      \endrst
  */
  GenericMechanical(SP::SolverOptions options);

  /** destructor
   */
  ~GenericMechanical();

  // GETTERS/SETTERS

  // --- Others functions ---

  /** initialize the GenericMechanical problem(compute topology ...)
   *   \param sim the simulation, owner of this OSNSPB
   */
  void initialize(SP::Simulation sim);

  /** Compute the unknown reaction and velocity and update the Interaction (y and lambda )
   *  \param time double current time
   *  \return int information about the solver convergence (0: ok, >0 problem, see Numerics documentation)
   */
  int compute(double time);

  /** compute extra-diagonal interactionBlock-matrix
    *  \param ed an edge descriptor
    */
  virtual void computeInteractionBlock(const InteractionsGraph::EDescriptor& ed);

  /** compute diagonal Interaction block
   * \param vd  a vertex descriptor
   */
  virtual void computeDiagonalInteractionBlock(const InteractionsGraph::VDescriptor& vd);

  /** print the data to the screen */
  void display() const;

  /** compute interactionBlocks if necessary (this depends on the type of
      OSNS, on the indexSets ...)
   */
  void updateInteractionBlocks();

  /** visitors hook
   */
  ACCEPT_STD_VISITORS();

};

#endif // GenericMechanical_H
<commit_msg>[kernel] change the default solver for frictional contact in GMP<commit_after>/* Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 *
 * Copyright 2018 INRIA.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/
/*! \file
  Fricton-Contact Non-Smooth Problem
*/
#ifndef GENERICMECHANICAL_H
#define GENERICMECHANICAL_H

#include "LinearOSNS.hpp"
#include "SiconosNumerics.h"
#include "Friction_cst.h" // from numerics, for solver id

TYPEDEF_SPTR(GenericMechanicalProblem)

/** Formalization and Resolution of a generic mechanical problem: It mixes bilateral equality, complementarity, impact and friction problems.
 *
 * This class is devoted to contains of a set of Non-Smooth Problem.
 *
 * \b Main functions:
 *  - formalization of the problem: computes M,q using the set of "active" Interactions from the simulation and \n
 *  the interactionBlock-matrices saved in the field interactionBlocks.\n
 *  Functions: initialize(), computeInteractionBlock(), preCompute()
 *  - solving of the GenericMechanical problem: function compute(), used to call solvers from Numerics through \n
 * the gmp_driver() interface of Numerics.
 *  - post-treatment of data: set values of y/lambda variables of the active Interaction (ie Interactions) using \n
 *  ouput results from the solver (velocity,reaction); function postCompute().
 *
 */
class GenericMechanical : public LinearOSNS
{
protected:
  /** serialization hooks */
  ACCEPT_SERIALIZATION(GenericMechanical);

  GenericMechanicalProblem * _pnumerics_GMP;

public:

  /** constructor from solver id
      \param numericsSolverId id of the internal friction solver of the generic problem
      default = SICONOS_FRICTION_3D_ONECONTACT_NSN
   */
  GenericMechanical(int FC3D_Solver_Id = SICONOS_FRICTION_3D_ONECONTACT_NSN);

  /** constructor from a pre-defined solver options set.
      \param options, the options set,
      \rst
      see :ref:`problems_and_solvers` for details.
      \endrst
  */
  GenericMechanical(SP::SolverOptions options);

  /** destructor
   */
  ~GenericMechanical();

  // GETTERS/SETTERS

  // --- Others functions ---

  /** initialize the GenericMechanical problem(compute topology ...)
   *   \param sim the simulation, owner of this OSNSPB
   */
  void initialize(SP::Simulation sim);

  /** Compute the unknown reaction and velocity and update the Interaction (y and lambda )
   *  \param time double current time
   *  \return int information about the solver convergence (0: ok, >0 problem, see Numerics documentation)
   */
  int compute(double time);

  /** compute extra-diagonal interactionBlock-matrix
    *  \param ed an edge descriptor
    */
  virtual void computeInteractionBlock(const InteractionsGraph::EDescriptor& ed);

  /** compute diagonal Interaction block
   * \param vd  a vertex descriptor
   */
  virtual void computeDiagonalInteractionBlock(const InteractionsGraph::VDescriptor& vd);

  /** print the data to the screen */
  void display() const;

  /** compute interactionBlocks if necessary (this depends on the type of
      OSNS, on the indexSets ...)
   */
  void updateInteractionBlocks();

  /** visitors hook
   */
  ACCEPT_STD_VISITORS();

};

#endif // GenericMechanical_H
<|endoftext|>