<commit_before>#include "HexShape.h"
#include "LinTetShape.h"
#include "QuadTetShape.h"
#include "BarShape.h"
#include "LMEShape.h"
#include "MRKPMShape.h"

using namespace voom;

int main()
{
  cout << endl << "Testing voom shape classes... " << endl;
  cout << ".............................." << endl << endl;

  // HexShape testing
  {
    cout << "Testing HexShape" << endl;
    Vector3d Point3D = Vector3d::Zero();
    srand( time(NULL) );
    Point3D(0) = 2.0*(Real(rand())/RAND_MAX - 0.5);
    Point3D(1) = 2.0*(Real(rand())/RAND_MAX - 0.5);
    Point3D(2) = 2.0*(Real(rand())/RAND_MAX - 0.5);

    HexShape HexShp(Point3D);
    HexShp.checkConsistency(Point3D);
    HexShp.checkPartitionUnity(Point3D);
  }

  // TetShape testing
  {
    Vector3d Point3D = Vector3d::Zero();
    srand( time(NULL) );
    Point3D(0) = 2.0*(Real(rand())/RAND_MAX - 0.5);
    Point3D(1) = 2.0*(Real(rand())/RAND_MAX - 0.5);
    Point3D(2) = 2.0*(Real(rand())/RAND_MAX - 0.5);

    cout << "Testing LinTetShape" << endl;
    LinTetShape LinTetShp(Point3D);
    LinTetShp.checkConsistency(Point3D);
    LinTetShp.checkPartitionUnity(Point3D);

    cout << "Testing QuadTetShape" << endl;
    QuadTetShape QuadTetShp(Point3D);
    QuadTetShp.checkConsistency(Point3D);
    QuadTetShp.checkPartitionUnity(Point3D);
  }

  // BarShape testing
  {
    cout << "Testing BarShape" << endl;
    VectorXd Point1D = VectorXd::Zero(1);
    srand( time(NULL) );
    Point1D(0) = 2.0*(Real(rand())/RAND_MAX - 0.5);

    BarShape BarShp(Point1D);
    BarShp.checkConsistency(Point1D);
    BarShp.checkPartitionUnity(Point1D);
  }

  // LMEshape testing
  {
    cout << "Testing LMEshape (cube domain)" << endl;
    vector<VectorXd > Nodes(8, Vector3d::Zero(3));
    Nodes[0] << 0.0, 0.0, 0.0;
    Nodes[1] << 1.0, 0.0, 0.0;
    Nodes[2] << 1.0, 1.0, 0.0;
    Nodes[3] << 0.0, 1.0, 0.0;
    Nodes[4] << 0.0, 0.0, 1.0;
    Nodes[5] << 1.0, 0.0, 1.0;
    Nodes[6] << 1.0, 1.0, 1.0;
    Nodes[7] << 0.0, 1.0, 1.0;
    VectorXd Point(3);
    Point << 0.4, 0.5, 0.6;
    Real beta = 0.8, tol = 1.0e-12;
    uint maxIter = 20;
    LMEShape LMEshp(Nodes, Point, beta, tol, maxIter);
    LMEshp.update(Point);

    cout << "Print LME at [0.4, 0.5, 0.6]" << endl;
    for (uint i=0; i<LMEshp.getShapeFunctionNum(); i++)
      {
	cout << "Node = " << i << " N = " << LMEshp.getN(i) << " DN = ";
	for (uint j=0; j<Point.size(); j++) {
	  cout << LMEshp.getDN(i,j) << " ";
	};
	cout << endl;
      };

    // Check consistency
    Point(0) = (Real(rand())/RAND_MAX );
    Point(1) = (Real(rand())/RAND_MAX );
    Point(2) = (Real(rand())/RAND_MAX );
    cout << "Check consistency at Point " << Point.transpose() << endl;
    LMEshp.checkConsistency(Point, 1.0e-8, 1.0e-6);
    LMEshp.checkPartitionUnity(Point);
    LMEshp.checkReproducingCondition(Point, 1.0e-6);
  }

  {
    cout << "Testing LMEshape (tet domain)" << endl;
    vector<VectorXd > Nodes(4, Vector3d::Zero(3));
    Nodes[0] << 0.0, 0.0, 0.0;
    Nodes[1] << 1.0, 0.0, 0.0;
    Nodes[2] << 0.0, 1.0, 0.0;
    Nodes[3] << 0.0, 0.0, 1.0;
    VectorXd Point(3);
    Point << 0.2, 0.1, 0.3;
    Real beta = 0.8, tol = 1.0e-12;
    uint maxIter = 20;
    LMEShape LMEshp(Nodes, Point, beta, tol, maxIter);
    LMEshp.update(Point);

    cout << "Print LME at [0.2, 0.1, 0.3]" << endl;
    for (uint i=0; i<LMEshp.getShapeFunctionNum(); i++)
      {
	cout << "Node = " << i << " N = " << LMEshp.getN(i) << " DN = ";
	for (uint j=0; j<Point.size(); j++) {
	  cout << LMEshp.getDN(i,j) << " ";
	};
	cout << endl;
      };

    // Check consistency
    Point(0) = (Real(rand())/RAND_MAX )*0.25;
    Point(1) = (Real(rand())/RAND_MAX )*0.25;
    Point(2) = (Real(rand())/RAND_MAX )*0.25;
    cout << "Check consistency at Point " << Point.transpose() << endl;
    LMEshp.checkConsistency(Point, 1.0e-8, 1.0e-6);
    LMEshp.checkPartitionUnity(Point);
    LMEshp.checkReproducingCondition(Point, 1.0e-6);
  }

  // MRKPMshape testing
  {
    // using same points as LME
    const Real radius = 0.001, support = 1.414, supportHat = 1.0;
    VectorXd Point2D(2);
    Point2D(0) = Point2D(1) = 0.5;

    vector<VectorXd > Nodes2D(4, Vector2d::Zero(2));
    Nodes2D[0] << 0.0, 0.0;
    Nodes2D[1] << 1.0, 0.0;
    Nodes2D[2] << 1.0, 1.0;
    Nodes2D[3] << 0.0, 1.0;
    MRKPMShape MRKPMshp(Nodes2D, Point2D, support, radius, supportHat);
    cout << "Print MRKPM at [0.5, 0.5]" << endl;
    for (uint i=0; i<MRKPMshp.getShapeFunctionNum(); i++)
      {
	cout << "Node = " << i << " N = " << MRKPMshp.getN(i) << " DN = ";
	for (uint j=0; j<Point2D.size(); j++) {
	  cout << MRKPMshp.getDN(i,j) << " ";
	};
	cout << endl;
      };

    Point2D(0) = (Real(rand())/RAND_MAX );
    Point2D(1) = (Real(rand())/RAND_MAX );
    cout << "Check consistency at Point " << Point2D.transpose() << endl;
    MRKPMshp.checkConsistency(Point2D, 1.0e-8, 1.0e-6);
    MRKPMshp.checkPartitionUnity(Point2D);
    MRKPMshp.checkReproducingCondition(Point2D, 1.0e-7);

  }

}
<commit_msg>New code<commit_after>#include "HexShape.h"
#include "LinTetShape.h"
#include "QuadTetShape.h"
#include "LinTriShape.h"
#include "QuadTriShape.h"
#include "BarShape.h"
#include "LMEShape.h"
#include "MRKPMShape.h"

using namespace voom;

int main()
{
  cout << endl << "Testing voom shape classes... " << endl;
  cout << ".............................." << endl << endl;

  // HexShape testing
  {
    cout << "Testing HexShape" << endl;
    Vector3d Point3D = Vector3d::Zero();
    srand( time(NULL) );
    Point3D(0) = 2.0*(Real(rand())/RAND_MAX - 0.5);
    Point3D(1) = 2.0*(Real(rand())/RAND_MAX - 0.5);
    Point3D(2) = 2.0*(Real(rand())/RAND_MAX - 0.5);

    HexShape HexShp(Point3D);
    HexShp.checkConsistency(Point3D);
    HexShp.checkPartitionUnity(Point3D);
  }

  // TetShape testing
  {
    Vector3d Point3D = Vector3d::Zero();
    srand( time(NULL) );
    Point3D(0) = 2.0*(Real(rand())/RAND_MAX - 0.5);
    Point3D(1) = 2.0*(Real(rand())/RAND_MAX - 0.5);
    Point3D(2) = 2.0*(Real(rand())/RAND_MAX - 0.5);

    cout << "Testing LinTetShape" << endl;
    LinTetShape LinTetShp(Point3D);
    LinTetShp.checkConsistency(Point3D);
    LinTetShp.checkPartitionUnity(Point3D);

    cout << "Testing QuadTetShape" << endl;
    QuadTetShape QuadTetShp(Point3D);
    QuadTetShp.checkConsistency(Point3D);
    QuadTetShp.checkPartitionUnity(Point3D);
  }

  // TriShape testing
  {
    Vector2d Point2D = Vector2d::Zero();
    srand( time(NULL) );
    Point2D(0) = 2.0*(Real(rand())/RAND_MAX - 0.5);
    Point2D(1) = 2.0*(Real(rand())/RAND_MAX - 0.5);

    cout << "Testing LinTriShape" << endl;
    LinTriShape LinTriShp(Point2D);
    LinTriShp.checkConsistency(Point2D);
    LinTriShp.checkPartitionUnity(Point2D);

    cout << "Testing QuadTriShape" << endl;
    QuadTriShape QuadTriShp(Point2D);
    QuadTriShp.checkConsistency(Point2D);
    QuadTriShp.checkPartitionUnity(Point2D);
  }

  // BarShape testing
  {
    cout << "Testing BarShape" << endl;
    VectorXd Point1D = VectorXd::Zero(1);
    srand( time(NULL) );
    Point1D(0) = 2.0*(Real(rand())/RAND_MAX - 0.5);

    BarShape BarShp(Point1D);
    BarShp.checkConsistency(Point1D);
    BarShp.checkPartitionUnity(Point1D);
  }

  // LMEshape testing
  {
    cout << "Testing LMEshape (cube domain)" << endl;
    vector<VectorXd > Nodes(8, Vector3d::Zero(3));
    Nodes[0] << 0.0, 0.0, 0.0;
    Nodes[1] << 1.0, 0.0, 0.0;
    Nodes[2] << 1.0, 1.0, 0.0;
    Nodes[3] << 0.0, 1.0, 0.0;
    Nodes[4] << 0.0, 0.0, 1.0;
    Nodes[5] << 1.0, 0.0, 1.0;
    Nodes[6] << 1.0, 1.0, 1.0;
    Nodes[7] << 0.0, 1.0, 1.0;
    VectorXd Point(3);
    Point << 0.4, 0.5, 0.6;
    Real beta = 0.8, tol = 1.0e-12;
    uint maxIter = 20;
    LMEShape LMEshp(Nodes, Point, beta, tol, maxIter);
    LMEshp.update(Point);

    cout << "Print LME at [0.4, 0.5, 0.6]" << endl;
    for (uint i=0; i<LMEshp.getShapeFunctionNum(); i++)
      {
	cout << "Node = " << i << " N = " << LMEshp.getN(i) << " DN = ";
	for (uint j=0; j<Point.size(); j++) {
	  cout << LMEshp.getDN(i,j) << " ";
	};
	cout << endl;
      };

    // Check consistency
    Point(0) = (Real(rand())/RAND_MAX );
    Point(1) = (Real(rand())/RAND_MAX );
    Point(2) = (Real(rand())/RAND_MAX );
    cout << "Check consistency at Point " << Point.transpose() << endl;
    LMEshp.checkConsistency(Point, 1.0e-8, 1.0e-6);
    LMEshp.checkPartitionUnity(Point);
    LMEshp.checkReproducingCondition(Point, 1.0e-6);
  }

  {
    cout << "Testing LMEshape (tet domain)" << endl;
    vector<VectorXd > Nodes(4, Vector3d::Zero(3));
    Nodes[0] << 0.0, 0.0, 0.0;
    Nodes[1] << 1.0, 0.0, 0.0;
    Nodes[2] << 0.0, 1.0, 0.0;
    Nodes[3] << 0.0, 0.0, 1.0;
    VectorXd Point(3);
    Point << 0.2, 0.1, 0.3;
    Real beta = 0.8, tol = 1.0e-12;
    uint maxIter = 20;
    LMEShape LMEshp(Nodes, Point, beta, tol, maxIter);
    LMEshp.update(Point);

    cout << "Print LME at [0.2, 0.1, 0.3]" << endl;
    for (uint i=0; i<LMEshp.getShapeFunctionNum(); i++)
      {
	cout << "Node = " << i << " N = " << LMEshp.getN(i) << " DN = ";
	for (uint j=0; j<Point.size(); j++) {
	  cout << LMEshp.getDN(i,j) << " ";
	};
	cout << endl;
      };

    // Check consistency
    Point(0) = (Real(rand())/RAND_MAX )*0.25;
    Point(1) = (Real(rand())/RAND_MAX )*0.25;
    Point(2) = (Real(rand())/RAND_MAX )*0.25;
    cout << "Check consistency at Point " << Point.transpose() << endl;
    LMEshp.checkConsistency(Point, 1.0e-8, 1.0e-6);
    LMEshp.checkPartitionUnity(Point);
    LMEshp.checkReproducingCondition(Point, 1.0e-6);
  }

  // MRKPMshape testing
  {
    // using same points as LME
    const Real radius = 0.001, support = 1.414, supportHat = 1.0;
    VectorXd Point2D(2);
    Point2D(0) = Point2D(1) = 0.5;

    vector<VectorXd > Nodes2D(4, Vector2d::Zero(2));
    Nodes2D[0] << 0.0, 0.0;
    Nodes2D[1] << 1.0, 0.0;
    Nodes2D[2] << 1.0, 1.0;
    Nodes2D[3] << 0.0, 1.0;
    MRKPMShape MRKPMshp(Nodes2D, Point2D, support, radius, supportHat);
    cout << "Print MRKPM at [0.5, 0.5]" << endl;
    for (uint i=0; i<MRKPMshp.getShapeFunctionNum(); i++)
      {
	cout << "Node = " << i << " N = " << MRKPMshp.getN(i) << " DN = ";
	for (uint j=0; j<Point2D.size(); j++) {
	  cout << MRKPMshp.getDN(i,j) << " ";
	};
	cout << endl;
      };

    Point2D(0) = (Real(rand())/RAND_MAX );
    Point2D(1) = (Real(rand())/RAND_MAX );
    cout << "Check consistency at Point " << Point2D.transpose() << endl;
    MRKPMshp.checkConsistency(Point2D, 1.0e-8, 1.0e-6);
    MRKPMshp.checkPartitionUnity(Point2D);
    MRKPMshp.checkReproducingCondition(Point2D, 1.0e-7);

  }

}
<|endoftext|>


<commit_before>// SolLimTests.cpp
#include <deque>
#include <map>
#include <gtest/gtest.h>

#include "SolLim.h"
#include "NuclideModel.h"
#include "CycException.h"
#include "Material.h"

using namespace std;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class SolLimTest : public ::testing::Test {
  protected:
    CompMapPtr test_comp_;
    mat_rsrc_ptr test_mat_;
    int one_mol_;
    int u235_, am241_;
    int u_;
    double test_size_;
    Radius r_four_, r_five_;
    Length len_five_;
    point_t origin_;
    int time_;
    double K_d_;

    virtual void SetUp(){
      // composition set up
      u235_=92235;
      u_=92;
      one_mol_=1.0;
      test_comp_= CompMapPtr(new CompMap(MASS));
      (*test_comp_)[u235_] = one_mol_;
      test_size_=10.0;
      // material creation
      test_mat_ = mat_rsrc_ptr(new Material(test_comp_));
      test_mat_->setQuantity(test_size_);
      // useful numbers
      K_d_ = 0.001;
    }
    virtual void TearDown() {
    }
};

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_f){
  double V_f, V_s, m_T;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=10.*i;
    // Generally meets expectations
    double expected = (m_T*V_s/V_f)*(1/(K_d_-K_d_*V_f/V_s + V_f/V_s));
    EXPECT_FLOAT_EQ(expected, SolLim::m_f(m_T, K_d_, V_s, V_f));
    // If the contaminant mass is zero, there is no m_f
    EXPECT_FLOAT_EQ(0, SolLim::m_f(0, K_d_, V_s, V_f));
    // If the K_d is zero, there is no sorption and m_f = m_T.
    EXPECT_FLOAT_EQ(m_T, SolLim::m_f(m_T, 0, V_s, V_f));
    // If solid volume is zero, there is no sorption and m_f = m_T.
    EXPECT_FLOAT_EQ(m_T, SolLim::m_f(m_T, K_d_, 0, V_f));
    // If fluid volume is zero, sorption is total and m_f = 0.
    EXPECT_FLOAT_EQ(0, SolLim::m_f(m_T, K_d_, V_s, 0));
  }

}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_s){
  double V_f, V_s, m_T;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    // Generally meets expectations
    double expected = K_d_*(V_s/V_f)*(m_T*V_s/V_f)*(1/(K_d_-K_d_*V_f/V_s + V_f/V_s));
    EXPECT_FLOAT_EQ(expected, SolLim::m_s(m_T, K_d_, V_s, V_f));
    // If the contaminant mass is zero, there is no m_T
    EXPECT_FLOAT_EQ(0, SolLim::m_s(0, K_d_, V_s, V_f));
    // If the K_d is zero, there is no sorption and m_s = 0.
    EXPECT_FLOAT_EQ(0, SolLim::m_s(m_T, 0, V_s, V_f));
    // If solid volume is zero, there is no sorption and m_s = 0
    EXPECT_FLOAT_EQ(0, SolLim::m_s(m_T, K_d_, 0, V_f));
    // If fluid volume is zero, sorption is total and m_s = m_T.
    EXPECT_FLOAT_EQ(m_T, SolLim::m_s(m_T, K_d_, V_s, 0));
    EXPECT_FLOAT_EQ((K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_s(m_T, K_d_, V_s, V_f));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ds){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(d*(K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ds(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ms){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ((1-d)*(K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ms(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ff){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(d*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ff(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_mf){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ((1-d)*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_mf(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_aff){
  double V_f, V_ff, V_s, m_T, d;
  double C_sol;
  double expected, mff;
  for(int c = 0; c<100; c++){
    C_sol = 0.1/c;
    for(int i=1; i<10; i++){
      V_f=0.1*i;
      V_s=0.1*i;
      m_T=0.1*i;
      d=0.1*i;
      V_ff=V_f*d;
      mff= SolLim::m_ff(m_T, K_d_, V_s, V_f, d);
      EXPECT_FLOAT_EQ(0, SolLim::m_aff(mff, V_ff, 0));
      expected = min(C_sol*V_ff, d*m_T/(1+K_d_*(V_s/V_f)));
      EXPECT_FLOAT_EQ(expected, SolLim::m_aff(mff, V_ff, C_sol));
      EXPECT_GE(mff, SolLim::m_aff(mff, V_ff, C_sol));
    }
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_aff_kd0){
  double V_f, V_ff, V_s, m_T, d;
  double C_sol;
  double expected, mff;
  for(int c = 0; c<100; c++){
    C_sol = 0.1/c;
    for(int i=1; i<10; i++){
      V_f=0.1*i;
      V_s=0.1*i;
      m_T=0.1*i;
      d=0.1*i;
      V_ff=V_f*d;
      mff= SolLim::m_ff(m_T, 0, V_s, V_f, d);
      EXPECT_FLOAT_EQ(0, SolLim::m_aff(mff, V_ff, 0));
      expected = min(C_sol*V_ff, d*m_T/(1+0*(V_s/V_f)));
      EXPECT_FLOAT_EQ(expected, SolLim::m_aff(mff, V_ff, C_sol));
      EXPECT_GE(mff, SolLim::m_aff(mff, V_ff, C_sol));
    }
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ps){
  double V_f, V_s, m_T, d;
  double C_sol = 0.001;
  double expected;
  double m_ff;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(0, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, 10000));
    m_ff = (d)*m_T/(1+K_d_*(V_s/V_f));
    expected = m_ff - min(C_sol*V_f, m_ff);
    EXPECT_FLOAT_EQ(expected, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, C_sol));
    EXPECT_FLOAT_EQ(expected, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, C_sol));
  }
}

<commit_msg>now we trust m_f so we can refer to it in other tests<commit_after>// SolLimTests.cpp
#include <deque>
#include <map>
#include <gtest/gtest.h>

#include "SolLim.h"
#include "NuclideModel.h"
#include "CycException.h"
#include "Material.h"

using namespace std;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class SolLimTest : public ::testing::Test {
  protected:
    CompMapPtr test_comp_;
    mat_rsrc_ptr test_mat_;
    int one_mol_;
    int u235_, am241_;
    int u_;
    double test_size_;
    Radius r_four_, r_five_;
    Length len_five_;
    point_t origin_;
    int time_;
    double K_d_;

    virtual void SetUp(){
      // composition set up
      u235_=92235;
      u_=92;
      one_mol_=1.0;
      test_comp_= CompMapPtr(new CompMap(MASS));
      (*test_comp_)[u235_] = one_mol_;
      test_size_=10.0;
      // material creation
      test_mat_ = mat_rsrc_ptr(new Material(test_comp_));
      test_mat_->setQuantity(test_size_);
      // useful numbers
      K_d_ = 0.001;
    }
    virtual void TearDown() {
    }
};

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_f){
  double V_f, V_s, m_T;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=10.*i;
    // Generally meets expectations
    double expected = (m_T*V_s/V_f)*(1/(K_d_-K_d_*V_f/V_s + V_f/V_s));
    EXPECT_FLOAT_EQ(expected, SolLim::m_f(m_T, K_d_, V_s, V_f));
    // If the contaminant mass is zero, there is no m_f
    EXPECT_FLOAT_EQ(0, SolLim::m_f(0, K_d_, V_s, V_f));
    // If the K_d is zero, there is no sorption and m_f = m_T.
    EXPECT_FLOAT_EQ(m_T, SolLim::m_f(m_T, 0, V_s, V_f));
    // If solid volume is zero, there is no sorption and m_f = m_T.
    EXPECT_FLOAT_EQ(m_T, SolLim::m_f(m_T, K_d_, 0, V_f));
    // If fluid volume is zero, sorption is total and m_f = 0.
    EXPECT_FLOAT_EQ(0, SolLim::m_f(m_T, K_d_, V_s, 0));
  }

}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_s){
  double V_f, V_s, m_T;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    // Generally meets expectations
    double expected = K_d_*(V_s/V_f)*(m_T*V_s/V_f)*(1/(K_d_-K_d_*V_f/V_s + V_f/V_s));
    EXPECT_FLOAT_EQ(expected, SolLim::m_s(m_T, K_d_, V_s, V_f));
    // If the contaminant mass is zero, there is no m_T
    EXPECT_FLOAT_EQ(0, SolLim::m_s(0, K_d_, V_s, V_f));
    // If the K_d is zero, there is no sorption and m_s = 0.
    EXPECT_FLOAT_EQ(0, SolLim::m_s(m_T, 0, V_s, V_f));
    // If solid volume is zero, there is no sorption and m_s = 0
    EXPECT_FLOAT_EQ(0, SolLim::m_s(m_T, K_d_, 0, V_f));
    // If fluid volume is zero, sorption is total and m_s = m_T.
    EXPECT_FLOAT_EQ(m_T, SolLim::m_s(m_T, K_d_, V_s, 0));
    EXPECT_FLOAT_EQ((K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_s(m_T, K_d_, V_s, V_f));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ds){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(d*(K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ds(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ms){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ((1-d)*(K_d_*(V_s/V_f))*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ms(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ff){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(d*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_ff(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_mf){
  double V_f, V_s, m_T, d;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ((1-d)*SolLim::m_f(m_T, K_d_,V_s, V_f), SolLim::m_mf(m_T, K_d_, V_s, V_f, d));
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_aff){
  double V_f, V_ff, V_s, m_T, d;
  double C_sol;
  double expected, mff;
  for(int c = 0; c<100; c++){
    C_sol = 0.1/c;
    for(int i=1; i<10; i++){
      V_f=0.1*i;
      V_s=0.1*i;
      m_T=0.1*i;
      d=0.1*i;
      V_ff=V_f*d;
      mff= SolLim::m_ff(m_T, K_d_, V_s, V_f, d);
      EXPECT_FLOAT_EQ(0, SolLim::m_aff(mff, V_ff, 0));
      expected = min(C_sol*V_ff, d*SolLim::m_f(m_T, K_d_, V_s, V_f));
      EXPECT_FLOAT_EQ(expected, SolLim::m_aff(mff, V_ff, C_sol));
      EXPECT_GE(mff, SolLim::m_aff(mff, V_ff, C_sol));
    }
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_aff_kd0){
  double V_f, V_ff, V_s, m_T, d;
  double C_sol;
  double expected, mff;
  for(int c = 0; c<100; c++){
    C_sol = 0.1/c;
    for(int i=1; i<10; i++){
      V_f=0.1*i;
      V_s=0.1*i;
      m_T=0.1*i;
      d=0.1*i;
      V_ff=V_f*d;
      mff= SolLim::m_ff(m_T, 0, V_s, V_f, d);
      EXPECT_FLOAT_EQ(0, SolLim::m_aff(mff, V_ff, 0));
      expected = min(C_sol*V_ff, d*SolLim::m_f(m_T, 0, V_s, V_f));
      EXPECT_FLOAT_EQ(expected, SolLim::m_aff(mff, V_ff, C_sol));
      EXPECT_GE(mff, SolLim::m_aff(mff, V_ff, C_sol));
    }
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(SolLimTest, m_ps){
  double V_f, V_s, m_T, d;
  double C_sol = 0.001;
  double expected;
  double m_ff;
  for(int i=1; i<10; i++){
    V_f=0.1*i;
    V_s=0.1*i;
    m_T=0.1*i;
    d=0.1*i;
    EXPECT_FLOAT_EQ(0, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, 10000));
    m_ff = (d)*m_T/(1+K_d_*(V_s/V_f));
    expected = m_ff - min(C_sol*V_f, m_ff);
    EXPECT_FLOAT_EQ(expected, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, C_sol));
    EXPECT_FLOAT_EQ(expected, SolLim::m_ps(m_T, K_d_, V_s, V_f, d, C_sol));
  }
}

<|endoftext|>


<commit_before>/* Copyright 2007-2015 QReal Research Group
 *
 * 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. */

#include "boundRegion.h"

#include <QtXml/QDomElement>

using namespace twoDModel::items;

const int defaultStroke = 0;

BoundRegion::BoundRegion(const QGraphicsObject &boundItem, const QString &boundId, QGraphicsItem *parent)
	: RegionItem(parent)
	, mBoundItem(boundItem)
	, mBoundId(boundId)
	, mStroke(defaultStroke)
{
	// We should dispose this item if bound item is deleted.
	connect(&mBoundItem, &QObject::destroyed, this, &QObject::deleteLater);
}

int BoundRegion::stroke() const
{
	return mStroke;
}

void BoundRegion::setStroke(int stroke)
{
	mStroke = stroke;
}

void BoundRegion::serialize(QDomElement &element)
{
	RegionItem::serialize(element);
	element.setAttribute("boundItem", mBoundId);
	element.setAttribute("stroke", mStroke);
}

void BoundRegion::deserialize(const QDomElement &element)
{
	RegionItem::deserialize(element);
	if (element.hasAttribute("stroke")) {
		bool ok = false;
		const int stroke = element.attribute("stroke").toInt(&ok);
		if (ok) {
			mStroke = stroke;
		}
	}
}

QRectF BoundRegion::boundingRect() const
{
	return mBoundItem.boundingRect().adjusted(-mStroke, -mStroke, mStroke, mStroke);
}

QPainterPath BoundRegion::shape() const
{
	if (!mStroke) {
		return mBoundItem.shape();
	}

	QPainterPathStroker stroker;
	stroker.setWidth(mStroke);
	return stroker.createStroke(mBoundItem.shape());
}

QString BoundRegion::regionType() const
{
	return "bound";
}
<commit_msg>Fixed holes in regions bound to line item<commit_after>/* Copyright 2007-2015 QReal Research Group
 *
 * 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. */

#include "boundRegion.h"

#include <src/engine/items/lineItem.h>

#include <QtXml/QDomElement>

using namespace twoDModel::items;

const int defaultStroke = 0;

BoundRegion::BoundRegion(const QGraphicsObject &boundItem, const QString &boundId, QGraphicsItem *parent)
	: RegionItem(parent)
	, mBoundItem(boundItem)
	, mBoundId(boundId)
	, mStroke(defaultStroke)
{
	// We should dispose this item if bound item is deleted.
	connect(&mBoundItem, &QObject::destroyed, this, &QObject::deleteLater);
}

int BoundRegion::stroke() const
{
	return mStroke;
}

void BoundRegion::setStroke(int stroke)
{
	mStroke = stroke;
}

void BoundRegion::serialize(QDomElement &element)
{
	RegionItem::serialize(element);
	element.setAttribute("boundItem", mBoundId);
	element.setAttribute("stroke", mStroke);
}

void BoundRegion::deserialize(const QDomElement &element)
{
	RegionItem::deserialize(element);
	if (element.hasAttribute("stroke")) {
		bool ok = false;
		const int stroke = element.attribute("stroke").toInt(&ok);
		if (ok) {
			mStroke = stroke;
		}
	}
}

QRectF BoundRegion::boundingRect() const
{
	return mBoundItem.boundingRect().adjusted(-mStroke, -mStroke, mStroke, mStroke);
}

QPainterPath BoundRegion::shape() const
{
	const QPainterPath originalShape = mBoundItem.shape();
	if (!mStroke) {
		return originalShape;
	}

	QPainterPathStroker stroker;
	stroker.setWidth(mStroke);
	const QPainterPath result = stroker.createStroke(originalShape);
	return dynamic_cast<const LineItem *>(&mBoundItem) ? result.united(originalShape) : result;
}

QString BoundRegion::regionType() const
{
	return "bound";
}
<|endoftext|>


<commit_before>#include <QtCore/QCoreApplication>
#include <QtWidgets/QApplication>
#include <QQmlApplicationEngine>
#include <QPluginLoader>
#include <QDebug>
#include "Tools.h"

using namespace sofa::qtquick;

int main(int argc, char **argv)
{
    // TODO: this command disable the multithreaded render loop, currently we need this on Linux/OSX because our implementation of the sofa interface is not thread-safe
    qputenv("QML_BAD_GUI_RENDER_LOOP", "1");

	QApplication app(argc, argv);
    app.addLibraryPath(QCoreApplication::applicationDirPath() + "/../lib/");

    // application specific settings
	app.setOrganizationName("Sofa");
	app.setApplicationName("qtQuickSofa");

    QSettings::setPath(QSettings::Format::IniFormat, QSettings::Scope::UserScope, "./user/config/");
    QSettings::setDefaultFormat(QSettings::Format::IniFormat);

    // use the default.ini settings if it is the first time the user launch the application
    Tools::useDefaultSettingsAtFirstLaunch();

    // plugin initialization
	QString pluginName("SofaQtQuickGUI");
#ifdef SOFA_LIBSUFFIX
	pluginName += sofa_tostring(SOFA_LIBSUFFIX);
#endif
	QPluginLoader pluginLoader(pluginName);

    // first call to instance() initialize the plugin
    if(0 == pluginLoader.instance()) {
        qCritical() << "SofaQtQuickGUI plugin has not been found!";
        return -1;
    }

    // launch the main script
    QQmlApplicationEngine applicationEngine;
    applicationEngine.addImportPath("qrc:/");
    applicationEngine.load(QUrl("qrc:/qml/Main.qml"));

    return app.exec();
}
<commit_msg>FIX application config path<commit_after>#include <QtCore/QCoreApplication>
#include <QtWidgets/QApplication>
#include <QQmlApplicationEngine>
#include <QPluginLoader>
#include <QDebug>
#include "Tools.h"

using namespace sofa::qtquick;

int main(int argc, char **argv)
{
    // TODO: this command disable the multithreaded render loop, currently we need this on Linux/OSX because our implementation of the sofa interface is not thread-safe
    qputenv("QML_BAD_GUI_RENDER_LOOP", "1");

	QApplication app(argc, argv);
    app.addLibraryPath(QCoreApplication::applicationDirPath() + "/../lib/");

    // application specific settings
	app.setOrganizationName("Sofa");
	app.setApplicationName("qtQuickSofa");

    QSettings::setPath(QSettings::Format::IniFormat, QSettings::Scope::UserScope, QCoreApplication::applicationDirPath() + "/config/");
    QSettings::setDefaultFormat(QSettings::Format::IniFormat);

    // use the default.ini settings if it is the first time the user launch the application
    Tools::useDefaultSettingsAtFirstLaunch();

    // plugin initialization
	QString pluginName("SofaQtQuickGUI");
#ifdef SOFA_LIBSUFFIX
	pluginName += sofa_tostring(SOFA_LIBSUFFIX);
#endif
	QPluginLoader pluginLoader(pluginName);

    // first call to instance() initialize the plugin
    if(0 == pluginLoader.instance()) {
        qCritical() << "SofaQtQuickGUI plugin has not been found!";
        return -1;
    }

    // launch the main script
    QQmlApplicationEngine applicationEngine;
    applicationEngine.addImportPath("qrc:/");
    applicationEngine.load(QUrl("qrc:/qml/Main.qml"));

    return app.exec();
}
<|endoftext|>


<commit_before>#include <pybind11/embed.h>
#include <iostream>
#include <string>

namespace py = pybind11;

#include "app_config_impl.h"
#include "load_module.h"

#pragma GCC visibility push(hidden)
class AppConfigImpl : public virtual AppConfig {
public:
    AppConfigImpl();
    virtual ~AppConfigImpl() = default;

public:
    virtual std::string GetEntry(const char * path, const char * default_value) override;
    virtual int64_t GetEntryInt64(const char * path, int64_t default_value) override;
    virtual uint64_t GetEntryUInt64(const char * path, uint64_t default_value) override;
    virtual bool GetEntryBool(const char * path, bool default_value) override;

    virtual bool LoadFromFile(const char * file_path) override;

private:
    void ResetDefaults();

    bool m_Loaded;
    py::object m_AppConfig;
};

std::shared_ptr<AppConfig> g_AppConfig {new AppConfigImpl()};

AppConfigImpl::AppConfigImpl()
{
    ResetDefaults();
}

std::string AppConfigImpl::GetEntry(const char * path, const char * default_value)
{
    return m_AppConfig.attr("get")(path, py::cast(default_value)).cast<std::string>();
}

int64_t AppConfigImpl::GetEntryInt64(const char * path, int64_t default_value)
{
    return m_AppConfig.attr("get")(path, py::cast(default_value)).cast<int64_t>();
}

uint64_t AppConfigImpl::GetEntryUInt64(const char * path, uint64_t default_value)
{
    return m_AppConfig.attr("get")(path, py::cast(default_value)).cast<uint64_t>();
}

bool AppConfigImpl::GetEntryBool(const char * path, bool default_value)
{
    return m_AppConfig.attr("get")(path, py::cast(default_value)).cast<bool>();
}

bool AppConfigImpl::LoadFromFile(const char * file_path)
{
    try
    {
        const char *module_content =
#include "app_config.inc"
                ;

        m_AppConfig = LoadModuleFromString(module_content,
                                           "app_config",
                                           "app_config.py").attr("load_config")(file_path);

        m_Loaded = true;
    }
    catch(std::exception & e)
    {
        std::cerr << "load configuration from file:"
                  << file_path
                  << " failed!"
                  << std::endl
                  << e.what()
                  << std::endl;
        m_Loaded = false;
    }
    catch(...)
    {
        std::cerr << "load configuration from file:"
                  << file_path
                  << " failed!"
                  << std::endl;
        PyErr_Print();
        m_Loaded = false;
    }

    return m_Loaded;
}

void AppConfigImpl::ResetDefaults()
{
    m_Loaded = false;
}

#pragma GCC visibility pop
<commit_msg>return default value if config is not loaded<commit_after>#include <pybind11/embed.h>
#include <iostream>
#include <string>

namespace py = pybind11;

#include "app_config_impl.h"
#include "load_module.h"

#pragma GCC visibility push(hidden)
class AppConfigImpl : public virtual AppConfig {
public:
    AppConfigImpl();
    virtual ~AppConfigImpl() = default;

public:
    virtual std::string GetEntry(const char * path, const char * default_value) override;
    virtual int64_t GetEntryInt64(const char * path, int64_t default_value) override;
    virtual uint64_t GetEntryUInt64(const char * path, uint64_t default_value) override;
    virtual bool GetEntryBool(const char * path, bool default_value) override;

    virtual bool LoadFromFile(const char * file_path) override;

private:
    void ResetDefaults();

    bool m_bLoaded;
    py::object m_AppConfig;
};

std::shared_ptr<AppConfig> g_AppConfig {new AppConfigImpl()};

AppConfigImpl::AppConfigImpl()
{
    ResetDefaults();
}

std::string AppConfigImpl::GetEntry(const char * path, const char * default_value)
{
    return m_bLoaded ? m_AppConfig.attr("get")(path, py::cast(default_value)).cast<std::string>() : default_value;
}

int64_t AppConfigImpl::GetEntryInt64(const char * path, int64_t default_value)
{
    return m_bLoaded ? m_AppConfig.attr("get")(path, py::cast(default_value)).cast<int64_t>() : default_value;
}

uint64_t AppConfigImpl::GetEntryUInt64(const char * path, uint64_t default_value)
{
    return m_bLoaded ? m_AppConfig.attr("get")(path, py::cast(default_value)).cast<uint64_t>() : default_value;
}

bool AppConfigImpl::GetEntryBool(const char * path, bool default_value)
{
    return m_bLoaded ? m_AppConfig.attr("get")(path, py::cast(default_value)).cast<bool>() : default_value;
}

bool AppConfigImpl::LoadFromFile(const char * file_path)
{
    try
    {
        const char *module_content =
#include "app_config.inc"
                ;

        m_AppConfig = LoadModuleFromString(module_content,
                                           "app_config",
                                           "app_config.py").attr("load_config")(file_path);

        m_bLoaded = true;
    }
    catch(std::exception & e)
    {
        std::cerr << "load configuration from file:"
                  << file_path
                  << " failed!"
                  << std::endl
                  << e.what()
                  << std::endl;
        m_bLoaded = false;
    }
    catch(...)
    {
        std::cerr << "load configuration from file:"
                  << file_path
                  << " failed!"
                  << std::endl;
        PyErr_Print();
        m_bLoaded = false;
    }

    return m_bLoaded;
}

void AppConfigImpl::ResetDefaults()
{
    m_bLoaded = false;
}

#pragma GCC visibility pop
<|endoftext|>


<commit_before>#include "vision/BackboardFinder.h"
#include "vision/BetterBinaryImage.h"
#include <math.h>
#include "WPILib.h"
#include "util/Logger.h"
#include "config/Constants.h"
#include "subsystems/Drive.h"

BackboardFinder::BackboardFinder(Drive* drive) : VisionProcess() {
  cameraLog_ = new Logger("/cameraLog.log");
  printf("Initting camera\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
  width_ = 0;
  vDiff_ = 0;
  constants_ = Constants::GetInstance();
  useTopForWidth_ = false;
  drive_ = drive;
  useSkew_ = true;
  //camera.WriteResolution(AxisCameraParams::kResolution_320x240);
}

double BackboardFinder::GetX() {
  if (-1.0 <= x_ && x_ <= 1.0) {
    return x_;
  } else {
  //  printf("Bad x val :( %f\n", x_);
    return 0;
  }
}

double BackboardFinder::GetHDiff() {
	return width_;
}
double BackboardFinder::GetVDiff() {
  return vDiff_;
}

bool BackboardFinder::SeesTarget() {
  return HasFreshTarget() && seesTarget_;
}

void BackboardFinder::LogCamera() {
  cameraLog_->Log("%f,%f,%f\n", GetX(), width_, vDiff_);
}

double BackboardFinder::GetDistance() {
	double w = width_;
	if (useTopForWidth_) {
	  w += 7; // difference between target width and side to side distance
	}
	return constants_->distanceCoeffA * pow(width_, 6) +
			constants_->distanceCoeffB * pow(width_, 5) +
			constants_->distanceCoeffC * pow(width_, 4) +
			constants_->distanceCoeffD * pow(width_, 3) +
			constants_->distanceCoeffE * pow(width_, 2) +
			constants_->distanceCoeffF * width_ + constants_->distanceCoeffG;
}

double BackboardFinder::GetAngle() {
	//normalized x location (-1 to 1) times the pixels along
	//that one side = number of pixels off
	//47/320 = degree/pixel based on fov/horizontal resolution
	//pixels * degrees / pixels = degrees
	//printf("get: %f\n", (float) GetX());
	double offset = Constants::GetInstance()->cameraOffset;
	double ret = GetX() * 160.0 * 47.0 / 320.0 + offset;
	if (useSkew_) {
		ret += (orientation_ * 2.0 / 18.0);
	}
	return ret;
}

void BackboardFinder::SetUseSkew(bool useSkew) {
	useSkew_ = useSkew;
}

void BackboardFinder::DoVision() {
  // Get image from camera
  AxisCamera &camera = AxisCamera::GetInstance("10.2.54.11");
  ColorImage img(IMAQ_IMAGE_RGB);
  if (!camera.GetImage(&img))
    return;
  //

  // RGB Threshold -> BinaryImage
  BinaryImage* bimg = img.ThresholdRGB((int)constants_->thresholdRMin, (int)constants_->thresholdRMax,
                                       (int)constants_->thresholdGMin, (int)constants_->thresholdGMax,
                                       (int)constants_->thresholdBMin, (int)constants_->thresholdBMax);

  // take out small things
  Image* image = bimg->GetImaqImage();
  if (!image)
    return;
  int pKernel[9] = {1,1,1,1,1,1,1,1,1};
  StructuringElement structElem;
  structElem.matrixCols = 3;
  structElem.matrixRows = 3;
  structElem.hexa = FALSE;
  structElem.kernel = pKernel;

  // Filters particles based on their size.
  imaqSizeFilter(image, image, TRUE, 1, IMAQ_KEEP_LARGE, &structElem);

  // Convex Hull
  imaqConvexHull(image, image, true);

  // Convex Hull Perimeter, pParamter = perimeter Paramater
  int pParameter[1] = {20};
  double pLower[1] = {0};
  double pUpper[1] = {100};
  int pCalibrated[1] = {0};
  int pExclude[1] = {0};

  ParticleFilterCriteria2* pParticleCriteria = NULL;
  ParticleFilterOptions pParticleFilterOptions;
  int pNumParticles;

  pParticleCriteria = (ParticleFilterCriteria2*)malloc(sizeof(ParticleFilterCriteria2));
  pParticleCriteria[0].parameter = (MeasurementType)pParameter[0];
  pParticleCriteria[0].lower = pLower[0];
  pParticleCriteria[0].upper = pUpper[0];
  pParticleCriteria[0].calibrated = pCalibrated[0];
  pParticleCriteria[0].exclude = pExclude[0];

  pParticleFilterOptions.rejectMatches = TRUE;
  pParticleFilterOptions.rejectBorder = 0;
  pParticleFilterOptions.connectivity8 = TRUE;
  imaqParticleFilter3(image, image, pParticleCriteria, 1, &pParticleFilterOptions, NULL, &pNumParticles);
  free(pParticleCriteria);

  // Filter based on squarishness, eParamter = elongationParamter
  int eParameter =  53;
  double eLower = 1.2;
  double eUpper = 2.7;
  int eCalibrated = 0;
  int eExclude = 0;
  ParticleFilterCriteria2* eParticleCriteria = NULL;
  ParticleFilterOptions eParticleFilterOptions;
  int eNumParticles;
  eParticleCriteria = (ParticleFilterCriteria2*)malloc(sizeof(ParticleFilterCriteria2));

  eParticleCriteria[0].parameter = (MeasurementType) eParameter;
  eParticleCriteria[0].lower = eLower;
  eParticleCriteria[0].upper = eUpper;
  eParticleCriteria[0].calibrated = eCalibrated;
  eParticleCriteria[0].exclude = eExclude;

  eParticleFilterOptions.rejectMatches = FALSE;
  eParticleFilterOptions.rejectBorder = 0;
  eParticleFilterOptions.connectivity8 = TRUE;
  imaqParticleFilter3(image, image, eParticleCriteria, 1, &eParticleFilterOptions, NULL, &eNumParticles);
  free(eParticleCriteria);

  // Extract Particles (4?)
  ParticleAnalysisReport left, right, top, bottom;
  vector<ParticleAnalysisReport>* particles = bimg->GetOrderedParticleAnalysisReports();

  // Find L,R,T,B based on CoM X,Y
  int i = 0;
#if 0
  switch (particles->size()) {

  case 4:
    for (i = 0; i < particles->size(); i++) {
      ParticleAnalysisReport p = (*particles)[i];
      if (i == 0) {
        left = top = right = bottom = p;
      }
      if (p.center_mass_x_normalized < left.center_mass_x_normalized) {
        left = p;
      }
      if (p.center_mass_x_normalized > right.center_mass_x_normalized) {
        right = p;
      }
      if (p.center_mass_y_normalized < top.center_mass_y_normalized) {
        top = p;
      }
      if (p.center_mass_y_normalized > bottom.center_mass_y_normalized) {
        bottom = p;
      }
    }
    break;
#define X_DELTA .1
#define Y_DELTA .2
#define IN_LINE_X(a,b)  (fabs(a.center_mass_x_normalized  - b.center_mass_x_normalized) < X_DELTA)
#define IN_LINE_Y(a,b)  (fabs(a.center_mass_y_normalized  - b.center_mass_y_normalized) < Y_DELTA)
#define HIGHEST(a,b)    ((a.center_mass_y_normalized < b.center_mass_y_normalized) ? a : b)
  case 3:
    // Two Horizontal or two vertical targets
    if (IN_LINE_Y(particles->at(0), particles->at(1))){
      printf("case A\n");
      top = particles->at(2);
    } else if (IN_LINE_Y(particles->at(1), particles->at(2))) {
      printf("case B\n");
      top = particles->at(0);
    } else if (IN_LINE_Y(particles->at(0), particles->at(2))){
      printf("case C\n");
      top = particles->at(1);
    } else if (IN_LINE_X(particles->at(0), particles->at(1))){
      printf("case D\n");
      top = HIGHEST(particles->at(0), particles->at(1));
    } else if (IN_LINE_X(particles->at(1), particles->at(2))){
      printf("case E\n");
      top = HIGHEST(particles->at(1), particles->at(2));
    } else if (IN_LINE_X(particles->at(0), particles->at(2))){
      printf("case F\n");
      top = HIGHEST(particles->at(0), particles->at(2));
    } else {
    	printf("case Q\n");
      // wtf, mate?
    }
    break;
  case 2:
    if (particles->at(0).center_mass_x_normalized > .3 && particles->at(1).center_mass_x_normalized > .3) {
      //case where they are both on the right side of the screen, center axis is the one more to the right
      //if it only sees 2, the other is the left
      if (particles->at(0).center_mass_x_normalized > particles->at(1).center_mass_x_normalized) {
        top = particles->at(0);
      } else {
        top = particles->at(1);
      }
    } else if (particles->at(0).center_mass_x_normalized < -.3 && particles->at(1).center_mass_x_normalized < -.3) {
      //case where both are on the left side of the screen, center axis is the one more to the left
      //if it only sees 2, because the other is to the right
      if (particles->at(0).center_mass_x_normalized < particles->at(1).center_mass_x_normalized) {
        top = particles->at(0);
      } else {
        top = particles->at(1);
      }
    } else if (fabs(particles->at(0).center_mass_x_normalized) < .3 && fabs(particles->at(1).center_mass_x_normalized) < .3) {
      //case where we can only see 2 in the center, possibly super zoomed in, both have same axis
      if (particles->at(0).center_mass_y_normalized > particles->at(1).center_mass_y_normalized) {
        top = particles->at(0);
      } else {
        top = particles->at(1);
      }
    } else if (fabs(particles->at(0).center_mass_y_normalized) > .3) {
      //case where one on the side is blocked and one is in the center
      //the one off from the center line is the top or bottom, central
      //axis is the same
      top = particles->at(0);
    } else {
      top = particles->at(1);
    }
    break;
  case 1:
    if (particles->at(0).center_mass_x_normalized > .5) {
      left = particles->at(0);
      top = particles->at(0);
      top.center_mass_x_normalized = 1;
    } else if (particles->at(0).center_mass_x_normalized < -.5) {
      right = particles->at(0);
      top = particles->at(0);
      top.center_mass_x_normalized = -1;
    } else {
      //same desired axis
      bottom = particles->at(0);
      top = particles->at(0);
    }
    //if it's not left or right and still see's them then the top is set
    break;
  default:
    break;
  }
#undef X_DELTA
#undef Y_DELTA
#undef IN_LINE_X
#undef IN_LINE_Y
#endif

  int topIndex = 0;
  for (int i = 0; i < particles->size(); i++){
	  ParticleAnalysisReport p = (*particles)[i];
	 if (i == 0){
		 top = p;
	 }
	 if (p.center_mass_y_normalized < top.center_mass_y_normalized) {
		 top = p;
		 topIndex = i;
	 }
  }

  // Orientation
  double orientation;
  if (particles->size() >=1 ) {
    bimg->ParticleMeasurement(topIndex, IMAQ_MT_ORIENTATION, &orientation);
  } else {
	  orientation = 0;
  }

  if (orientation > 90) {
	  orientation -= 180;
  }
  orientation_ = orientation;

  // Calculate x offset from target center
  seesTarget_ = (particles->size() >= 1) && particles->size() < 5;
  x_ = seesTarget_ ? top.center_mass_x_normalized : 0.0;

  // Calculate angle on fieled based on ?

  width_ = top.boundingRect.width;

  printf("num particles: %d\n", particles->size());
  for (int i = 0; i < particles->size(); i++){
    printf("* i:%d | x:%f y:%f\n", i , particles->at(i).center_mass_x_normalized, particles->at(i).center_mass_y_normalized );
  }
  printf("or: %f\n\n", orientation_);

  static Logger * l = new Logger("/vision.csv");
  //l->Log("%f,%d,%d,%d\n", drive_->GetLeftEncoderDistance(),particles->size(), (right.boundingRect.left  - (left.boundingRect.left + left.boundingRect.width)), top.boundingRect.width );

  delete bimg;
  static double t = 0;
  double diff = Timer::GetFPGATimestamp() - t;
  t = Timer::GetFPGATimestamp();

  lastUpdate_ = t;

  double middleGap = right.boundingRect.left - (left.boundingRect.left + left.boundingRect.width);

}

bool BackboardFinder::HasFreshTarget() {
  return (Timer::GetFPGATimestamp() - lastUpdate_ < .5); // 500ms
}

<commit_msg>Fixed the unordered orientation report bug<commit_after>#include "vision/BackboardFinder.h"
#include "vision/BetterBinaryImage.h"
#include <math.h>
#include "WPILib.h"
#include "util/Logger.h"
#include "config/Constants.h"
#include "subsystems/Drive.h"

BackboardFinder::BackboardFinder(Drive* drive) : VisionProcess() {
  cameraLog_ = new Logger("/cameraLog.log");
  printf("Initting camera\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
  width_ = 0;
  vDiff_ = 0;
  constants_ = Constants::GetInstance();
  useTopForWidth_ = false;
  drive_ = drive;
  useSkew_ = true;
  //camera.WriteResolution(AxisCameraParams::kResolution_320x240);
}

double BackboardFinder::GetX() {
  if (-1.0 <= x_ && x_ <= 1.0) {
    return x_;
  } else {
  //  printf("Bad x val :( %f\n", x_);
    return 0;
  }
}

double BackboardFinder::GetHDiff() {
	return width_;
}
double BackboardFinder::GetVDiff() {
  return vDiff_;
}

bool BackboardFinder::SeesTarget() {
  return HasFreshTarget() && seesTarget_;
}

void BackboardFinder::LogCamera() {
  cameraLog_->Log("%f,%f,%f\n", GetX(), width_, vDiff_);
}

double BackboardFinder::GetDistance() {
	double w = width_;
	if (useTopForWidth_) {
	  w += 7; // difference between target width and side to side distance
	}
	return constants_->distanceCoeffA * pow(width_, 6) +
			constants_->distanceCoeffB * pow(width_, 5) +
			constants_->distanceCoeffC * pow(width_, 4) +
			constants_->distanceCoeffD * pow(width_, 3) +
			constants_->distanceCoeffE * pow(width_, 2) +
			constants_->distanceCoeffF * width_ + constants_->distanceCoeffG;
}

double BackboardFinder::GetAngle() {
	//normalized x location (-1 to 1) times the pixels along
	//that one side = number of pixels off
	//47/320 = degree/pixel based on fov/horizontal resolution
	//pixels * degrees / pixels = degrees
	//printf("get: %f\n", (float) GetX());
	double offset = Constants::GetInstance()->cameraOffset;
	double ret = GetX() * 160.0 * 47.0 / 320.0 + offset;
	if (useSkew_) {
		ret += (orientation_ * 2.0 / 18.0);
	}
	return ret;
}

void BackboardFinder::SetUseSkew(bool useSkew) {
	useSkew_ = useSkew;
}

void BackboardFinder::DoVision() {
  // Get image from camera
  AxisCamera &camera = AxisCamera::GetInstance("10.2.54.11");
  ColorImage img(IMAQ_IMAGE_RGB);
  if (!camera.GetImage(&img))
    return;
  //

  // RGB Threshold -> BinaryImage
  BinaryImage* bimg = img.ThresholdRGB((int)constants_->thresholdRMin, (int)constants_->thresholdRMax,
                                       (int)constants_->thresholdGMin, (int)constants_->thresholdGMax,
                                       (int)constants_->thresholdBMin, (int)constants_->thresholdBMax);

  // take out small things
  Image* image = bimg->GetImaqImage();
  if (!image)
    return;
  int pKernel[9] = {1,1,1,1,1,1,1,1,1};
  StructuringElement structElem;
  structElem.matrixCols = 3;
  structElem.matrixRows = 3;
  structElem.hexa = FALSE;
  structElem.kernel = pKernel;

  // Filters particles based on their size.
  imaqSizeFilter(image, image, TRUE, 1, IMAQ_KEEP_LARGE, &structElem);

  // Convex Hull
  imaqConvexHull(image, image, true);

  // Convex Hull Perimeter, pParamter = perimeter Paramater
  int pParameter[1] = {20};
  double pLower[1] = {0};
  double pUpper[1] = {100};
  int pCalibrated[1] = {0};
  int pExclude[1] = {0};

  ParticleFilterCriteria2* pParticleCriteria = NULL;
  ParticleFilterOptions pParticleFilterOptions;
  int pNumParticles;

  pParticleCriteria = (ParticleFilterCriteria2*)malloc(sizeof(ParticleFilterCriteria2));
  pParticleCriteria[0].parameter = (MeasurementType)pParameter[0];
  pParticleCriteria[0].lower = pLower[0];
  pParticleCriteria[0].upper = pUpper[0];
  pParticleCriteria[0].calibrated = pCalibrated[0];
  pParticleCriteria[0].exclude = pExclude[0];

  pParticleFilterOptions.rejectMatches = TRUE;
  pParticleFilterOptions.rejectBorder = 0;
  pParticleFilterOptions.connectivity8 = TRUE;
  imaqParticleFilter3(image, image, pParticleCriteria, 1, &pParticleFilterOptions, NULL, &pNumParticles);
  free(pParticleCriteria);

  // Filter based on squarishness, eParamter = elongationParamter
  int eParameter =  53;
  double eLower = 1.2;
  double eUpper = 2.7;
  int eCalibrated = 0;
  int eExclude = 0;
  ParticleFilterCriteria2* eParticleCriteria = NULL;
  ParticleFilterOptions eParticleFilterOptions;
  int eNumParticles;
  eParticleCriteria = (ParticleFilterCriteria2*)malloc(sizeof(ParticleFilterCriteria2));

  eParticleCriteria[0].parameter = (MeasurementType) eParameter;
  eParticleCriteria[0].lower = eLower;
  eParticleCriteria[0].upper = eUpper;
  eParticleCriteria[0].calibrated = eCalibrated;
  eParticleCriteria[0].exclude = eExclude;

  eParticleFilterOptions.rejectMatches = FALSE;
  eParticleFilterOptions.rejectBorder = 0;
  eParticleFilterOptions.connectivity8 = TRUE;
  imaqParticleFilter3(image, image, eParticleCriteria, 1, &eParticleFilterOptions, NULL, &eNumParticles);
  free(eParticleCriteria);

  // Extract Particles (4?)
  ParticleAnalysisReport top;
  vector<ParticleAnalysisReport>* particles = new vector<ParticleAnalysisReport>;
  int particleCount = bimg->GetNumberParticles();
  for(int particleIndex = 0; particleIndex < particleCount; particleIndex++)
  {
  	particles->push_back(bimg->GetParticleAnalysisReport(particleIndex));
  }

  // Find top target
  int topIndex = 0;
  for (int i = 0; i < particles->size(); i++){
	 ParticleAnalysisReport p = (*particles)[i];
	 if (i == 0){
		 top = p;
	 }
	 if (p.center_mass_y_normalized < top.center_mass_y_normalized) {
		 top = p;
		 topIndex = i;
	 }
  }

  // Skew of target gives us our lateral position on the field
  double orientation =0;
  int comx = 0;
  if (particles->size() >=1 ) {
    bimg->ParticleMeasurement(topIndex, IMAQ_MT_ORIENTATION, &orientation);
    bimg->ParticleMeasurement(topIndex, IMAQ_MT_CENTER_OF_MASS_X, &comx);
  } else {
	  orientation = 0;
  }

  if (orientation > 90) {
	  orientation -= 180;
  }
  orientation_ = orientation;

  // Calculate x offset from target center
  seesTarget_ = (particles->size() >= 1) && particles->size() < 5;
  x_ = seesTarget_ ? top.center_mass_x_normalized : 0.0;

  // Calculate angle on fieled based on ?

  width_ = top.boundingRect.width;

#if 0
  int comx2 = 0;
  printf("num particles: %d\n", particles->size());
  for (int i = 0; i < particles->size(); i++){
	bimg->ParticleMeasurement(i, IMAQ_MT_ORIENTATION, &orientation);
	 bimg->ParticleMeasurement(i, IMAQ_MT_CENTER_OF_MASS_X, &comx2);
    printf("* i:%d | x:%d y:%f or:%f comx2:%d\n", i , particles->at(i).center_mass_x, particles->at(i).center_mass_y_normalized, orientation, comx2 );
  }
  printf("topIndex:%d\ncomxq:%d\nor: %f\n\n", topIndex, comx, orientation_);
#endif

  static Logger * l = new Logger("/vision.csv");
  //l->Log("%f,%d,%d,%d\n", drive_->GetLeftEncoderDistance(),particles->size(), (right.boundingRect.left  - (left.boundingRect.left + left.boundingRect.width)), top.boundingRect.width );

  delete bimg;
  static double t = 0;
  double diff = Timer::GetFPGATimestamp() - t;
  t = Timer::GetFPGATimestamp();
  lastUpdate_ = t;
}

bool BackboardFinder::HasFreshTarget() {
  return (Timer::GetFPGATimestamp() - lastUpdate_ < .5); // 500ms
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2009, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

// This file *must* remain with absolutely no run-time dependency.

#include <string>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <libport/windows.hh>
#include <libport/foreach.hh>

#include "urbi-root.hh"

#define ECHO(S)                                 \
  std::cerr << S << std::endl

// Quick hackish portability layer. We cannot use the one from libport as
// it is not header-only.
#ifdef WIN32
#define RTLD_LAZY 0
#define RTLD_GLOBAL 0

static HMODULE
dlopen(const char* name, int)
{
  HMODULE res = LoadLibrary(name);
  if (res)
  {
    char buf[BUFSIZ];
    GetModuleFileName(res, buf, sizeof buf - 1);
    buf[sizeof buf - 1] = 0;
    ECHO("loaded: " << buf);
  }
  return res;
}

static void*
dlsym(HMODULE module, const char* name)
{
  return GetProcAddress(module, name);
}

static const char*
dlerror(DWORD err = GetLastError())
{
  static char buf[1024];

  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                0, err, 0,
                (LPTSTR)buf, sizeof buf,
                0);

  return buf;
}

static strings_type
split(std::string lib)
{
  strings_type res;
  size_t pos;
  while ((pos = lib.find_first_of(':')) != lib.npos)
  {
    std::string s = lib.substr(0, pos);
    lib = lib.substr(pos + 1, lib.npos);
    // In case we split "c:\foo" into "c" and "\foo", glue them
    // together again.
    if (s[0] == '\\'
        && !res.empty()
        && res.back().length() == 1)
      res.back() += ':' + s;
    else
      res.push_back(s);
  }
  if (!lib.empty())
    res.push_back(lib);
  return res;
}
#else
typedef void* HMODULE;
# include <dlfcn.h>
#endif

std::string
xgetenv(const char* var)
{
  const char* res = getenv(var);
  return res ? res : "";
}

void
xsetenv(const std::string& var, const std::string& val, int force)
{
#ifdef WIN32
  if (force || xgetenv(var).empty())
    _putenv(strdup((var + "=" + val).c_str()));
#else
  setenv(var.c_str(), val.c_str(), force);
#endif
}

/// Main. Load liburbi and call urbi_launch
int main(int argc, char* argv[])
{
  /* Unfortunately, shared object search path cannot be modified once
   * the program has started under linux (see dlopen(3)).
   * Plan A would be to load our dependencies manualy, which implies
   * knowing all of them and keeping this file up-to-date.
   * Plan B is simpler: setenv and exec
   */
  std::string urbi_root = get_urbi_root(argv[0]);
  std::string libdir = urbi_root + "/" + lib_rel_path;

  std::string ld_lib_path = xgetenv(LD_LIBRARY_PATH_NAME);

  // Only set URBI_ROOT if not already present.
  xsetenv("URBI_ROOT", urbi_root, 0);

#ifndef WIN32
  // Look if what we need is in (DY)LD_LIBRARY_PATH. Proceed if it is.
  // Otherwise, add it and exec ourselve to retry.
  if (ld_lib_path.find(libdir) == ld_lib_path.npos)
  {
    xsetenv(LD_LIBRARY_PATH_NAME, ld_lib_path + ":" + libdir, 1);
    execv(argv[0], argv);
  }
#else
  std::string path = xgetenv("PATH");
  strings_type ldpath_list = split(ld_lib_path);
  foreach(const std::string& s, ldpath_list)
    path += ";" + s;
  ECHO("ENV PATH=" << path);
  xsetenv("PATH", path, 1);
#endif

  std::string liburbi_path = std::string() + libdir + "/liburbi" + lib_ext;

  // First try using LIBRARY_PATH in the environment.
  HMODULE handle = dlopen((std::string("liburbi") + lib_ext).c_str(),
                          RTLD_LAZY | RTLD_GLOBAL);

  // If it fails, force path based on URBI_ROOT.
  if (!handle)
    handle = dlopen(liburbi_path.c_str(), RTLD_LAZY | RTLD_GLOBAL);
  if (!handle)
  {
    ECHO("cannot open liburbi: " << liburbi_path << ':' << dlerror());
    ECHO(getenv(LD_LIBRARY_PATH_NAME));
    return 1;
  }
  typedef int(*main_t)(int, char*[]);
  main_t urbi_launch = (main_t)dlsym(handle, "urbi_launch");
  if (!urbi_launch)
  {
    ECHO("cannot locate urbi_launch symbol: " << dlerror());
    return 2;
  }
  return urbi_launch(argc, argv);
}
<commit_msg>urbi-launch: fix win32 code.<commit_after>/*
 * Copyright (C) 2009, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

// This file *must* remain with absolutely no run-time dependency.

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <libport/foreach.hh>
#include <libport/windows.hh>
#include <list>
#include <string>

#include "urbi-root.hh"

#define ECHO(S)                                 \
  std::cerr << S << std::endl

// Quick hackish portability layer. We cannot use the one from libport as
// it is not header-only.
#ifdef WIN32
#define RTLD_LAZY 0
#define RTLD_GLOBAL 0

static HMODULE
dlopen(const char* name, int)
{
  HMODULE res = LoadLibrary(name);
  if (res)
  {
    char buf[BUFSIZ];
    GetModuleFileName(res, buf, sizeof buf - 1);
    buf[sizeof buf - 1] = 0;
    ECHO("loaded: " << buf);
  }
  return res;
}

static void*
dlsym(HMODULE module, const char* name)
{
  return GetProcAddress(module, name);
}

static const char*
dlerror(DWORD err = GetLastError())
{
  static char buf[1024];

  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                0, err, 0,
                (LPTSTR)buf, sizeof buf,
                0);

  return buf;
}

typedef std::list<std::string> strings_type;
static strings_type
split(std::string lib)
{
  strings_type res;
  size_t pos;
  while ((pos = lib.find_first_of(':')) != lib.npos)
  {
    std::string s = lib.substr(0, pos);
    lib = lib.substr(pos + 1, lib.npos);
    // In case we split "c:\foo" into "c" and "\foo", glue them
    // together again.
    if (s[0] == '\\'
        && !res.empty()
        && res.back().length() == 1)
      res.back() += ':' + s;
    else
      res.push_back(s);
  }
  if (!lib.empty())
    res.push_back(lib);
  return res;
}
#else
typedef void* HMODULE;
# include <dlfcn.h>
#endif

std::string
xgetenv(const std::string& var)
{
  const char* res = getenv(var.c_str());
  return res ? res : "";
}

void
xsetenv(const std::string& var, const std::string& val, int force)
{
#ifdef WIN32
  if (force || xgetenv(var).empty())
    _putenv(strdup((var + "=" + val).c_str()));
#else
  setenv(var.c_str(), val.c_str(), force);
#endif
}

/// Main. Load liburbi and call urbi_launch
int main(int argc, char* argv[])
{
  /* Unfortunately, shared object search path cannot be modified once
   * the program has started under linux (see dlopen(3)).
   * Plan A would be to load our dependencies manualy, which implies
   * knowing all of them and keeping this file up-to-date.
   * Plan B is simpler: setenv and exec
   */
  std::string urbi_root = get_urbi_root(argv[0]);
  std::string libdir = urbi_root + "/" + lib_rel_path;

  std::string ld_lib_path = xgetenv(LD_LIBRARY_PATH_NAME);

  // Only set URBI_ROOT if not already present.
  xsetenv("URBI_ROOT", urbi_root, 0);

#ifndef WIN32
  // Look if what we need is in (DY)LD_LIBRARY_PATH. Proceed if it is.
  // Otherwise, add it and exec ourselve to retry.
  if (ld_lib_path.find(libdir) == ld_lib_path.npos)
  {
    xsetenv(LD_LIBRARY_PATH_NAME, ld_lib_path + ":" + libdir, 1);
    execv(argv[0], argv);
  }
#else
  std::string path = xgetenv("PATH");
  strings_type ldpath_list = split(ld_lib_path);
  foreach(const std::string& s, ldpath_list)
    path += ";" + s;
  ECHO("ENV PATH=" << path);
  xsetenv("PATH", path, 1);
#endif

  std::string liburbi_path = std::string() + libdir + "/liburbi" + lib_ext;

  // First try using LIBRARY_PATH in the environment.
  HMODULE handle = dlopen((std::string("liburbi") + lib_ext).c_str(),
                          RTLD_LAZY | RTLD_GLOBAL);

  // If it fails, force path based on URBI_ROOT.
  if (!handle)
    handle = dlopen(liburbi_path.c_str(), RTLD_LAZY | RTLD_GLOBAL);
  if (!handle)
  {
    ECHO("cannot open liburbi: " << liburbi_path << ':' << dlerror());
    ECHO(getenv(LD_LIBRARY_PATH_NAME));
    return 1;
  }
  typedef int(*main_t)(int, char*[]);
  main_t urbi_launch = (main_t)dlsym(handle, "urbi_launch");
  if (!urbi_launch)
  {
    ECHO("cannot locate urbi_launch symbol: " << dlerror());
    return 2;
  }
  return urbi_launch(argc, argv);
}
<|endoftext|>


<commit_before>#include "chimera/colladaDB/ColladaMaterial.hpp"
#include "chimera/colladaDB/ColladaShader.hpp"
#include "chimera/core/visible/Components.hpp"
#include "chimera/core/visible/TextureManager.hpp"

namespace Chimera {

ColladaMaterial::~ColladaMaterial() {}

Texture* ColladaMaterial::loadImage(pugi::xml_node nodeParent, const std::string& url) {

    pugi::xml_node node = getLibrary("library_images", url); // FIXME!!!
    pugi::xml_node init = node.child("init_from");
    if (init != nullptr) {
        pugi::xml_text pathFile = init.text();
        if (pathFile != nullptr) {
            std::string f = pathFile.as_string();
            SDL_Log("Nova textura %s, Key: %s", f.c_str(), url.c_str());

            TextureManager::loadFromFile(url, f, TexParam());
            return TextureManager::getLast();
        }
    }

    throw std::string("Textura nao encontrada: " + url);
}

void ColladaMaterial::createEffect(Material* pMat, pugi::xml_node nodeParent) {

    std::unordered_map<std::string, Texture*> mapaTex;
    std::unordered_map<std::string, std::string> mapa2D;

    for (pugi::xml_node param = nodeParent.first_child(); param; param = param.next_sibling()) {

        std::string sProf = param.name();
        std::string sid = param.attribute("sid").value();
        if (sProf == "newparam") {

            pugi::xml_node val1 = param.first_child();
            std::string sVal1 = val1.name();

            if (sVal1 == "surface") {

                std::string keyImage = val1.child("init_from").text().as_string();
                Texture* tex = loadImage(val1, keyImage);
                mapaTex[sid] = tex;

            } else if (sVal1 == "sampler2D") {

                std::string keyMap = val1.child("source").text().as_string();
                mapa2D[sid] = keyMap;
            }

        } else if (sProf == "technique") {

            pugi::xml_node phong = param.child("phong");
            for (pugi::xml_node prop = phong.first_child(); prop; prop = prop.next_sibling()) {

                std::string p = prop.name();
                if (p == "emission") {

                    pugi::xml_node first = prop.first_child();
                    if (std::string(first.name()) == "color")
                        pMat->setEmission(textToVec4(first.text().as_string()));
                    else if (std::string(first.name()) == "texture") {
                        // TODO: implementar
                    }

                } else if (p == "ambient") {
                    pugi::xml_node first = prop.first_child();
                    if (std::string(first.name()) == "color")
                        pMat->setAmbient(textToVec4(first.text().as_string()));
                    else if (std::string(first.name()) == "texture") {
                        // TODO: implementar
                    }
                } else if (p == "diffuse") {
                    pugi::xml_node first = prop.first_child();
                    if (std::string(first.name()) == "color")
                        pMat->setDiffuse(textToVec4(first.text().as_string()));
                    else if (std::string(first.name()) == "texture") {
                        std::string sAddr = first.attribute("texture").value();
                        std::string sAddr2 = mapa2D[sAddr];
                        Texture* tex = mapaTex[sAddr2];

                        pMat->addTexture(SHADE_TEXTURE_DIFFUSE, tex);
                        pMat->setDiffuse(glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); // FIXME: Arquivo do blender nao tem!!
                    }
                } else if (p == "specular") {
                    pugi::xml_node first = prop.first_child();
                    if (std::string(first.name()) == "color")
                        pMat->setSpecular(textToVec4(first.text().as_string()));
                    else if (std::string(first.name()) == "texture") {
                        // TODO: implementar
                    }
                } else if (p == "shininess") {
                    // TODO: implementar

                    pugi::xml_node first = prop.first_child();
                    if (std::string(first.name()) == "float") {
                        float aa = first.text().as_float();
                        pMat->setShine(aa);
                    }

                } else if (p == "index_of_refraction") {
                    // TODO: implementar
                }
            }
        }
    }
}

void ColladaMaterial::create(Entity& entity, pugi::xml_node nodeParent) {

    std::string refName = "";

    pugi::xml_node material = getLibrary("library_materials", nodeParent.attribute("symbol").value());
    pugi::xml_node instanceEffect = material.child("instance_effect");
    pugi::xml_node technique_hint = instanceEffect.child("technique_hint");

    if (technique_hint != nullptr) {
        if (std::string(technique_hint.attribute("profile").value()) == "GLSL")
            refName = technique_hint.attribute("ref").value();
    }

    pugi::xml_node effect = getLibrary("library_effects", instanceEffect.attribute("url").value());

    ComponentMaterial& eMaterial = entity.addComponent<ComponentMaterial>();
    eMaterial.tag.id = material.attribute("id").value();
    eMaterial.tag.tag = material.attribute("name").value();
    eMaterial.tag.serial = Collada::getNewSerial();

    pugi::xml_node profile = effect.child("profile_COMMON");
    if (profile != nullptr)
        createEffect(eMaterial.material, profile);

    pugi::xml_node extra = effect.child("extra");
    if (extra != nullptr) {

        pugi::xml_node instanceEffectShade = extra.child("instance_effect");
        std::string url = instanceEffectShade.attribute("url").value();

        ColladaShader cs(colladaDom, url);
        cs.create(refName, entity, cs.getLibrary("library_effects", url));

    } else {

        pugi::xml_node profileGLSL = effect.child("profile_GLSL");
        if (profileGLSL != nullptr) {

            ColladaShader cs(colladaDom, refName);
            cs.create(refName, entity, profileGLSL);
        }
    }
}
} // namespace Chimera<commit_msg>ProfileGLSL tambem funciona em mateial<commit_after>#include "chimera/colladaDB/ColladaMaterial.hpp"
#include "chimera/colladaDB/ColladaShader.hpp"
#include "chimera/core/visible/Components.hpp"
#include "chimera/core/visible/TextureManager.hpp"

namespace Chimera {

ColladaMaterial::~ColladaMaterial() {}

Texture* ColladaMaterial::loadImage(pugi::xml_node nodeParent, const std::string& url) {

    pugi::xml_node node = getLibrary("library_images", url); // FIXME!!!
    pugi::xml_node init = node.child("init_from");
    if (init != nullptr) {
        pugi::xml_text pathFile = init.text();
        if (pathFile != nullptr) {
            std::string f = pathFile.as_string();
            SDL_Log("Nova textura %s, Key: %s", f.c_str(), url.c_str());

            TextureManager::loadFromFile(url, f, TexParam());
            return TextureManager::getLast();
        }
    }

    throw std::string("Textura nao encontrada: " + url);
}

void ColladaMaterial::createEffect(Material* pMat, pugi::xml_node nodeParent) {

    std::unordered_map<std::string, Texture*> mapaTex;
    std::unordered_map<std::string, std::string> mapa2D;

    for (pugi::xml_node param = nodeParent.first_child(); param; param = param.next_sibling()) {

        std::string sProf = param.name();
        std::string sid = param.attribute("sid").value();
        if (sProf == "newparam") {

            pugi::xml_node val1 = param.first_child();
            std::string sVal1 = val1.name();

            if (sVal1 == "surface") {

                std::string keyImage = val1.child("init_from").text().as_string();
                Texture* tex = loadImage(val1, keyImage);
                mapaTex[sid] = tex;

            } else if (sVal1 == "sampler2D") {

                std::string keyMap = val1.child("source").text().as_string();
                mapa2D[sid] = keyMap;
            }

        } else if (sProf == "technique") {

            pugi::xml_node phong = param.child("phong");
            for (pugi::xml_node prop = phong.first_child(); prop; prop = prop.next_sibling()) {

                std::string p = prop.name();
                if (p == "emission") {

                    pugi::xml_node first = prop.first_child();
                    if (std::string(first.name()) == "color")
                        pMat->setEmission(textToVec4(first.text().as_string()));
                    else if (std::string(first.name()) == "texture") {
                        // TODO: implementar
                    }

                } else if (p == "ambient") {
                    pugi::xml_node first = prop.first_child();
                    if (std::string(first.name()) == "color")
                        pMat->setAmbient(textToVec4(first.text().as_string()));
                    else if (std::string(first.name()) == "texture") {
                        // TODO: implementar
                    }
                } else if (p == "diffuse") {
                    pugi::xml_node first = prop.first_child();
                    if (std::string(first.name()) == "color")
                        pMat->setDiffuse(textToVec4(first.text().as_string()));
                    else if (std::string(first.name()) == "texture") {
                        std::string sAddr = first.attribute("texture").value();
                        std::string sAddr2 = mapa2D[sAddr];
                        Texture* tex = mapaTex[sAddr2];

                        pMat->addTexture(SHADE_TEXTURE_DIFFUSE, tex);
                        pMat->setDiffuse(glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); // FIXME: Arquivo do blender nao tem!!
                    }
                } else if (p == "specular") {
                    pugi::xml_node first = prop.first_child();
                    if (std::string(first.name()) == "color")
                        pMat->setSpecular(textToVec4(first.text().as_string()));
                    else if (std::string(first.name()) == "texture") {
                        // TODO: implementar
                    }
                } else if (p == "shininess") {
                    // TODO: implementar

                    pugi::xml_node first = prop.first_child();
                    if (std::string(first.name()) == "float") {
                        float aa = first.text().as_float();
                        pMat->setShine(aa);
                    }

                } else if (p == "index_of_refraction") {
                    // TODO: implementar
                }
            }
        }
    }
}

void ColladaMaterial::create(Entity& entity, pugi::xml_node nodeParent) {

    std::string refName = "";

    pugi::xml_node material = getLibrary("library_materials", nodeParent.attribute("symbol").value());
    pugi::xml_node instanceEffect = material.child("instance_effect");
    pugi::xml_node technique_hint = instanceEffect.child("technique_hint");

    if (technique_hint != nullptr) {
        if (std::string(technique_hint.attribute("profile").value()) == "GLSL")
            refName = technique_hint.attribute("ref").value();
    }

    pugi::xml_node effect = getLibrary("library_effects", instanceEffect.attribute("url").value());

    ComponentMaterial& eMaterial = entity.addComponent<ComponentMaterial>();
    eMaterial.tag.id = material.attribute("id").value();
    eMaterial.tag.tag = material.attribute("name").value();
    eMaterial.tag.serial = Collada::getNewSerial();

    pugi::xml_node profile = effect.child("profile_COMMON");
    if (profile != nullptr)
        createEffect(eMaterial.material, profile);

    pugi::xml_node extra = effect.child("extra");
    if (extra != nullptr) {

        pugi::xml_node instanceEffectShade = extra.child("instance_effect");
        std::string url = instanceEffectShade.attribute("url").value();

        ColladaShader cs(colladaDom, url);
        cs.create(refName, entity, cs.getLibrary("library_effects", url));

    } else {

        pugi::xml_node profileGLSL = effect.child("profile_GLSL");
        if (profileGLSL != nullptr) {

            ColladaShader cs(colladaDom, refName);
            cs.create(refName, entity, effect); // get profileGLSL inside here
        }
    }
}
} // namespace Chimera<|endoftext|>


<commit_before>/*
 * Copyright (c) 2009 The University of Edinburgh
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Timothy M. Jones
 */

#ifndef __ARCH_POWER_REGISTERS_HH__
#define __ARCH_POWER_REGISTERS_HH__

#include "arch/power/generated/max_inst_regs.hh"
#include "arch/power/miscregs.hh"

namespace PowerISA {

using PowerISAInst::MaxInstSrcRegs;
using PowerISAInst::MaxInstDestRegs;
using PowerISAInst::MaxMiscDestRegs;

typedef uint8_t RegIndex;

typedef uint64_t IntReg;

// Floating point register file entry type
typedef uint64_t FloatRegBits;
typedef double FloatReg;
typedef uint64_t MiscReg;

// Constants Related to the number of registers
const int NumIntArchRegs = 32;

// CR, XER, LR, CTR, FPSCR, RSV, RSV-LEN, RSV-ADDR
// and zero register, which doesn't actually exist but needs a number
const int NumIntSpecialRegs = 9;
const int NumFloatArchRegs = 32;
const int NumFloatSpecialRegs = 0;
const int NumInternalProcRegs = 0;

const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
const int NumMiscRegs = NUM_MISCREGS;

// Semantically meaningful register indices
const int ReturnValueReg = 3;
const int ArgumentReg0 = 3;
const int ArgumentReg1 = 4;
const int ArgumentReg2 = 5;
const int ArgumentReg3 = 6;
const int ArgumentReg4 = 7;
const int FramePointerReg = 31;
const int StackPointerReg = 1;

// There isn't one in Power, but we need to define one somewhere
const int ZeroReg = NumIntRegs - 1;

const int SyscallNumReg = 0;
const int SyscallPseudoReturnReg = 3;
const int SyscallSuccessReg = 3;

// These help enumerate all the registers for dependence tracking.
const int FP_Base_DepTag = NumIntRegs;
const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs;
const int Max_DepTag = Ctrl_Base_DepTag + NumMiscRegs;

typedef union {
    IntReg   intreg;
    FloatReg fpreg;
    MiscReg  ctrlreg;
} AnyReg;

enum MiscIntRegNums {
    INTREG_CR = NumIntArchRegs,
    INTREG_XER,
    INTREG_LR,
    INTREG_CTR,
    INTREG_FPSCR,
    INTREG_RSV,
    INTREG_RSV_LEN,
    INTREG_RSV_ADDR
};

} // namespace PowerISA

#endif // __ARCH_POWER_REGISTERS_HH__
<commit_msg>Power: Fix MaxMiscDestRegs which was set to zero<commit_after>/*
 * Copyright (c) 2009 The University of Edinburgh
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Timothy M. Jones
 */

#ifndef __ARCH_POWER_REGISTERS_HH__
#define __ARCH_POWER_REGISTERS_HH__

#include "arch/power/generated/max_inst_regs.hh"
#include "arch/power/miscregs.hh"

namespace PowerISA {

using PowerISAInst::MaxInstSrcRegs;
using PowerISAInst::MaxInstDestRegs;

// Power writes a misc register outside of the isa parser, so it can't
// be detected by it. Manually add it here.
const int MaxMiscDestRegs = PowerISAInst::MaxMiscDestRegs + 1;

typedef uint8_t RegIndex;

typedef uint64_t IntReg;

// Floating point register file entry type
typedef uint64_t FloatRegBits;
typedef double FloatReg;
typedef uint64_t MiscReg;

// Constants Related to the number of registers
const int NumIntArchRegs = 32;

// CR, XER, LR, CTR, FPSCR, RSV, RSV-LEN, RSV-ADDR
// and zero register, which doesn't actually exist but needs a number
const int NumIntSpecialRegs = 9;
const int NumFloatArchRegs = 32;
const int NumFloatSpecialRegs = 0;
const int NumInternalProcRegs = 0;

const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
const int NumMiscRegs = NUM_MISCREGS;

// Semantically meaningful register indices
const int ReturnValueReg = 3;
const int ArgumentReg0 = 3;
const int ArgumentReg1 = 4;
const int ArgumentReg2 = 5;
const int ArgumentReg3 = 6;
const int ArgumentReg4 = 7;
const int FramePointerReg = 31;
const int StackPointerReg = 1;

// There isn't one in Power, but we need to define one somewhere
const int ZeroReg = NumIntRegs - 1;

const int SyscallNumReg = 0;
const int SyscallPseudoReturnReg = 3;
const int SyscallSuccessReg = 3;

// These help enumerate all the registers for dependence tracking.
const int FP_Base_DepTag = NumIntRegs;
const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs;
const int Max_DepTag = Ctrl_Base_DepTag + NumMiscRegs;

typedef union {
    IntReg   intreg;
    FloatReg fpreg;
    MiscReg  ctrlreg;
} AnyReg;

enum MiscIntRegNums {
    INTREG_CR = NumIntArchRegs,
    INTREG_XER,
    INTREG_LR,
    INTREG_CTR,
    INTREG_FPSCR,
    INTREG_RSV,
    INTREG_RSV_LEN,
    INTREG_RSV_ADDR
};

} // namespace PowerISA

#endif // __ARCH_POWER_REGISTERS_HH__
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008-2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/// \file libuobject/main.cc

#include <libport/cstdio>
#include <libport/unistd.h>
#include <libport/cerrno>

#include <iostream>
#include <list>
#include <sstream>

#include <libport/cli.hh>
#include <libport/containers.hh>
#include <libport/foreach.hh>
#include <libport/lexical-cast.hh>
#include <libport/package-info.hh>
#include <libport/program-name.hh>
#include <libport/sysexits.hh>

#include <urbi/package-info.hh>
#include <urbi/uexternal.hh>
#include <urbi/umain.hh>
#include <urbi/umessage.hh>
#include <urbi/uobject.hh>
#include <urbi/urbi-root.hh>
#include <urbi/usyncclient.hh>
#include <libuobject/remote-ucontext-impl.hh>
using libport::program_name;

namespace urbi
{
  static impl::RemoteUContextImpl* defaultContext;

  UCallbackAction
  debug(const UMessage& msg)
  {
    msg.client.printf("DEBUG: got a message: %s\n",
                      string_cast(msg).c_str());
    return URBI_CONTINUE;
  }

  UCallbackAction
  static
  endProgram(const UMessage& msg)
  {
    msg.client.printf("ERROR: got a disconnection message: %s\n",
                      string_cast(msg).c_str());
    exit(1);
    return URBI_CONTINUE; //stupid gcc
  }

  static
  void
  usage()
  {
    std::cout <<
      "usage:\n" << libport::program_name() << " [OPTION]...\n"
      "\n"
      "Options:\n"
      "  -b, --buffer SIZE     input buffer size"
		 << " [" << UAbstractClient::URBI_BUFLEN << "]\n"
      "  -h, --help            display this message and exit\n"
      "  -H, --host ADDR       server host name"
                 << " [" << UClient::default_host() << "]\n"
      "      --server          put remote in server mode\n"
      "      --no-sync-client  Use UClient instead of USyncClient\n"
      "  -p, --port PORT       tcp port URBI will listen to"
		 << " [" << UAbstractClient::URBI_PORT << "]\n"
      "  -r, --port-file FILE  file containing the port to listen to\n"
      "  -V, --version         print version information and exit\n"
      "  -d, --disconnect      exit program if disconnected(defaults)\n"
      "  -s, --stay-alive      do not exit program if disconnected\n"
		 << libport::exit (EX_OK);
  }

  static
  void
  version()
  {
    std::cout << urbi::package_info() << std::endl
              << libport::exit (EX_OK);
  }

  typedef std::vector<std::string> files_type;
  int
  initialize(const std::string& host, int port, size_t buflen,
	     bool exitOnDisconnect, bool server, const files_type& files,
             bool useSyncClient)
  {
    std::cerr << program_name()
	      << ": " << urbi::package_info() << std::endl
	      << program_name()
	      << ": Remote Component Running on "
	      << host << " " << port << std::endl;
    if (useSyncClient)
    {
      USyncClient::options o;
      o.server(server);
      new USyncClient(host, port, buflen, o);
    }
    else
    {
      std::cerr << "#WARNING: the no-sync-client mode is dangerous.\n"
	"Any attempt to use synchronous operation will crash your program."
        << std::endl;
      UClient::options o;
      o.server(server);
      setDefaultClient(new UClient(host, port, buflen, o));
    }
    if (exitOnDisconnect)
    {
      if (!getDefaultClient() || getDefaultClient()->error())
	std::cerr << "ERROR: failed to connect, exiting..." << std::endl
		  << libport::exit(1);
      getDefaultClient()->setClientErrorCallback(callback(&endProgram));
    }
    if (!getDefaultClient() || getDefaultClient()->error())
      return 1;
    defaultContext = new impl::RemoteUContextImpl(
      (USyncClient*)dynamic_cast<UClient*>(getDefaultClient()));

#ifdef LIBURBIDEBUG
    getDefaultClient()->setWildcardCallback(callback(&debug));
#else
    getDefaultClient()->setErrorCallback(callback(&debug));
#endif

    // Wait for client to be connected if in server mode.
    while (getDefaultClient()
           && !getDefaultClient()->error()
           && !getDefaultClient()->init())
      usleep(20000);

    // Waiting for connectionID.
    while (getDefaultClient()
           && getDefaultClient()->connectionID() == "")
      usleep(5000);
    defaultContext->init();
   //baseURBIStarter::init();
    // Send a ';' since UObject likely sent a serie of piped commands.
    URBI_SEND_COMMAND("");
    // Load initialization files.
    foreach (const std::string& file, files)
      getDefaultClient()->sendFile(file);
    return 0;
  }

  namespace
  {
    static
    void
    argument_with_option(const char* longopt,
                         char shortopt,
                         const std::string& val)
    {
      std::cerr
        << program_name()
        << ": warning: arguments without options are deprecated"
        << std::endl
        << "use `-" << shortopt << ' ' << val << '\''
        << " or `--" << longopt << ' ' << val << "' instead"
        << std::endl
        << "Try `" << program_name() << " --help' for more information."
        << std::endl;
    }

  }

  URBI_SDK_API int
  main(const libport::cli_args_type& args, UrbiRoot&, bool block, bool)
  {
    std::string host = UClient::default_host();
    bool exitOnDisconnect = true;
    int port = UAbstractClient::URBI_PORT;
    bool server = false;
    bool useSyncClient = true;
    size_t buflen = UAbstractClient::URBI_BUFLEN;
    // Files to load
    files_type files;

    // The number of the next (non-option) argument.
    unsigned argp = 1;
    for (unsigned i = 1; i < args.size(); ++i)
    {
      const std::string& arg = args[i];
      if (arg == "--buffer" || arg == "-b")
	buflen = libport::convert_argument<size_t>(args, i++);
      else if (arg == "--disconnect" || arg == "-d")
	exitOnDisconnect = true;
      else if (arg == "--file" || arg == "-f")
        files.push_back(libport::convert_argument<const char*>(args, i++));
      else if (arg == "--stay-alive" || arg == "-s")
	exitOnDisconnect = false;
      else if (arg == "--help" || arg == "-h")
	usage();
      else if (arg == "--host" || arg == "-H")
	host = libport::convert_argument<std::string>(args, i++);
      else if (arg == "--no-sync-client")
        useSyncClient = false;
      else if (arg == "--port" || arg == "-p")
	port = libport::convert_argument<unsigned>(args, i++);
      else if (arg == "--port-file" || arg == "-r")
	port =
          (libport::file_contents_get<int>
           (libport::convert_argument<const char*>(args, i++)));
      else if (arg == "--server")
	server = true;
      // FIXME: Remove -v some day.
      else if (arg == "--version" || arg == "-V" || arg == "-v")
	version();
      else if (arg[0] == '-')
	libport::invalid_option(arg);
      else
	// A genuine argument.
	switch (argp++)
	{
	  case 1:
            argument_with_option("host", 'H', args[i]);
	    host = args[i];
	    break;
	  case 2:
            argument_with_option("port", 'p', args[i]);
	    port = libport::convert_argument<unsigned> ("port", args[i].c_str());
	    break;
	  default:
	    std::cerr << "unexpected argument: " << arg << std::endl
		      << libport::exit(EX_USAGE);
	}
    }

    initialize(host, port, buflen, exitOnDisconnect, server, files,
               useSyncClient);

    if (block)
      while (true)
        usleep(30000000);
    return 0;
  }

}
<commit_msg>Add --describe and --describe-file options to remote mode.<commit_after>/*
 * Copyright (C) 2008-2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/// \file libuobject/main.cc

#include <libport/cstdio>
#include <libport/unistd.h>
#include <libport/cerrno>

#include <iostream>
#include <list>
#include <sstream>

#include <libport/cli.hh>
#include <libport/containers.hh>
#include <libport/foreach.hh>
#include <libport/lexical-cast.hh>
#include <libport/package-info.hh>
#include <libport/program-name.hh>
#include <libport/sysexits.hh>

#include <urbi/package-info.hh>
#include <urbi/uexternal.hh>
#include <urbi/umain.hh>
#include <urbi/umessage.hh>
#include <urbi/uobject.hh>
#include <urbi/urbi-root.hh>
#include <urbi/usyncclient.hh>
#include <libuobject/remote-ucontext-impl.hh>
using libport::program_name;

namespace urbi
{
  static impl::RemoteUContextImpl* defaultContext;

  UCallbackAction
  debug(const UMessage& msg)
  {
    msg.client.printf("DEBUG: got a message: %s\n",
                      string_cast(msg).c_str());
    return URBI_CONTINUE;
  }

  UCallbackAction
  static
  endProgram(const UMessage& msg)
  {
    msg.client.printf("ERROR: got a disconnection message: %s\n",
                      string_cast(msg).c_str());
    exit(1);
    return URBI_CONTINUE; //stupid gcc
  }

  static
  void
  usage()
  {
    std::cout <<
      "usage:\n" << libport::program_name() << " [OPTION]...\n"
      "\n"
      "Options:\n"
      "  -b, --buffer SIZE     input buffer size"
		 << " [" << UAbstractClient::URBI_BUFLEN << "]\n"
      "  -h, --help            display this message and exit\n"
      "  -H, --host ADDR       server host name"
                 << " [" << UClient::default_host() << "]\n"
      "      --server          put remote in server mode\n"
      "      --no-sync-client  Use UClient instead of USyncClient\n"
      "  -p, --port PORT       tcp port URBI will listen to"
		 << " [" << UAbstractClient::URBI_PORT << "]\n"
      "  -r, --port-file FILE  file containing the port to listen to\n"
      "  -V, --version         print version information and exit\n"
      "  -d, --disconnect      exit program if disconnected(defaults)\n"
      "  -s, --stay-alive      do not exit program if disconnected\n"
      "  --describe            describe loaded UObjects and exit\n"
      "  --describe-file FILE  write the list of present UObjects to FILE\n"
		 << libport::exit (EX_OK);
  }

  static
  void
  version()
  {
    std::cout << urbi::package_info() << std::endl
              << libport::exit (EX_OK);
  }

  typedef std::vector<std::string> files_type;
  int
  initialize(const std::string& host, int port, size_t buflen,
	     bool exitOnDisconnect, bool server, const files_type& files,
             bool useSyncClient)
  {
    std::cerr << program_name()
	      << ": " << urbi::package_info() << std::endl
	      << program_name()
	      << ": Remote Component Running on "
	      << host << " " << port << std::endl;
    if (useSyncClient)
    {
      USyncClient::options o;
      o.server(server);
      new USyncClient(host, port, buflen, o);
    }
    else
    {
      std::cerr << "#WARNING: the no-sync-client mode is dangerous.\n"
	"Any attempt to use synchronous operation will crash your program."
        << std::endl;
      UClient::options o;
      o.server(server);
      setDefaultClient(new UClient(host, port, buflen, o));
    }
    if (exitOnDisconnect)
    {
      if (!getDefaultClient() || getDefaultClient()->error())
	std::cerr << "ERROR: failed to connect, exiting..." << std::endl
		  << libport::exit(1);
      getDefaultClient()->setClientErrorCallback(callback(&endProgram));
    }
    if (!getDefaultClient() || getDefaultClient()->error())
      return 1;
    defaultContext = new impl::RemoteUContextImpl(
      (USyncClient*)dynamic_cast<UClient*>(getDefaultClient()));

#ifdef LIBURBIDEBUG
    getDefaultClient()->setWildcardCallback(callback(&debug));
#else
    getDefaultClient()->setErrorCallback(callback(&debug));
#endif

    // Wait for client to be connected if in server mode.
    while (getDefaultClient()
           && !getDefaultClient()->error()
           && !getDefaultClient()->init())
      usleep(20000);

    // Waiting for connectionID.
    while (getDefaultClient()
           && getDefaultClient()->connectionID() == "")
      usleep(5000);
    defaultContext->init();
   //baseURBIStarter::init();
    // Send a ';' since UObject likely sent a serie of piped commands.
    URBI_SEND_COMMAND("");
    // Load initialization files.
    foreach (const std::string& file, files)
      getDefaultClient()->sendFile(file);
    return 0;
  }

  namespace
  {
    static
    void
    argument_with_option(const char* longopt,
                         char shortopt,
                         const std::string& val)
    {
      std::cerr
        << program_name()
        << ": warning: arguments without options are deprecated"
        << std::endl
        << "use `-" << shortopt << ' ' << val << '\''
        << " or `--" << longopt << ' ' << val << "' instead"
        << std::endl
        << "Try `" << program_name() << " --help' for more information."
        << std::endl;
    }

  }

  URBI_SDK_API int
  main(const libport::cli_args_type& args, UrbiRoot&, bool block, bool)
  {
    std::string host = UClient::default_host();
    bool exitOnDisconnect = true;
    int port = UAbstractClient::URBI_PORT;
    bool server = false;
    bool useSyncClient = true;
    bool describeMode = false;
    std::string describeFile;
    size_t buflen = UAbstractClient::URBI_BUFLEN;
    // Files to load
    files_type files;

    // The number of the next (non-option) argument.
    unsigned argp = 1;
    for (unsigned i = 1; i < args.size(); ++i)
    {
      const std::string& arg = args[i];
      if (arg == "--buffer" || arg == "-b")
	buflen = libport::convert_argument<size_t>(args, i++);
      else if (arg == "--disconnect" || arg == "-d")
	exitOnDisconnect = true;
      else if (arg == "--file" || arg == "-f")
        files.push_back(libport::convert_argument<const char*>(args, i++));
      else if (arg == "--stay-alive" || arg == "-s")
	exitOnDisconnect = false;
      else if (arg == "--help" || arg == "-h")
	usage();
      else if (arg == "--host" || arg == "-H")
	host = libport::convert_argument<std::string>(args, i++);
      else if (arg == "--no-sync-client")
        useSyncClient = false;
      else if (arg == "--port" || arg == "-p")
	port = libport::convert_argument<unsigned>(args, i++);
      else if (arg == "--port-file" || arg == "-r")
	port =
          (libport::file_contents_get<int>
           (libport::convert_argument<const char*>(args, i++)));
      else if (arg == "--server")
	server = true;
      // FIXME: Remove -v some day.
      else if (arg == "--version" || arg == "-V" || arg == "-v")
	version();
      else if (arg == "--describe")
	describeMode = true;
      else if (arg == "--describe-file")
         describeFile = libport::convert_argument<const char*>(args, i++);
      else if (arg[0] == '-')
	libport::invalid_option(arg);
      else
	// A genuine argument.
	switch (argp++)
	{
	  case 1:
            argument_with_option("host", 'H', args[i]);
	    host = args[i];
	    break;
	  case 2:
            argument_with_option("port", 'p', args[i]);
	    port = libport::convert_argument<unsigned> ("port", args[i].c_str());
	    break;
	  default:
	    std::cerr << "unexpected argument: " << arg << std::endl
		      << libport::exit(EX_USAGE);
	}
    }

    if (describeMode)
    {
      foreach(baseURBIStarter* s, baseURBIStarter::list())
        std::cout << s->name << std::endl;
      foreach(baseURBIStarterHub* s, baseURBIStarterHub::list())
        std::cout << s->name << std::endl;
      return 0;
    }
    if (!describeFile.empty())
    {
      std::ofstream of(describeFile.c_str());
      foreach(baseURBIStarter* s, baseURBIStarter::list())
        of << s->name << std::endl;
      foreach(baseURBIStarterHub* s, baseURBIStarterHub::list())
        of << s->name << std::endl;
    }
    initialize(host, port, buflen, exitOnDisconnect, server, files,
               useSyncClient);

    if (block)
      while (true)
        usleep(30000000);
    return 0;
  }

}
<|endoftext|>