// Launch unit test.
  EUnitTestResult test()
  { CALL
    CPoint3D<Tsint> point;
    UT_ASSERT_EQUAL_POINTS(point, 0, 0, 0);

    point.set(10, 20, 30);
    UT_ASSERT_EQUAL_POINTS(point, 10, 20, 30);

    point.negate();
    UT_ASSERT_EQUAL_POINTS(point, -10, -20, -30);

    point.absolute();
    UT_ASSERT_EQUAL_POINTS(point, 10, 20, 30);

    point += 20;
    UT_ASSERT_EQUAL_POINTS(point, 30, 40, 50);

    point -= 50;
    UT_ASSERT_EQUAL_POINTS(point, -20, -10, 0);

    point.clear();
    UT_ASSERT_EQUAL_POINTS(point, 0, 0, 0);

    UT_ACCEPT;
  }
Esempio n. 2
0
/*---------------------------------------------------------------
						getMean
  Returns an estimate of the pose, (the mean, or mathematical expectation of the
 PDF)
 ---------------------------------------------------------------*/
void CPointPDFSOG::getMean(CPoint3D& p) const
{
	size_t N = m_modes.size();
	double X = 0, Y = 0, Z = 0;

	if (N)
	{
		CListGaussianModes::const_iterator it;
		double sumW = 0;

		for (it = m_modes.begin(); it != m_modes.end(); ++it)
		{
			double w;
			sumW += w = exp(it->log_w);
			X += it->val.mean.x() * w;
			Y += it->val.mean.y() * w;
			Z += it->val.mean.z() * w;
		}
		if (sumW > 0)
		{
			X /= sumW;
			Y /= sumW;
			Z /= sumW;
		}
	}

	p.x(X);
	p.y(Y);
	p.z(Z);
}
Esempio n. 3
0
/*---------------------------------------------------------------
The operator u'="this"+u is the pose/point compounding operator.
 ---------------------------------------------------------------*/
CPoint3D CPose2D::operator + (const CPoint3D& u)const
{
	update_cached_cos_sin();

	return CPoint3D(
		m_coords[0] + u.x() * m_cosphi - u.y() * m_sinphi,
		m_coords[1] + u.x() * m_sinphi + u.y() * m_cosphi,
		u.z() );
}
Esempio n. 4
0
void TestGeometry3D2()
{
	CPose3D iniPoseVehicle(745.327749,407.959716,14.851070,-2.985091,0.009412,0.051315);

	CPoint3D GPSPosOnVehicle(-0.25,0,0.10);

	CPoint3D iniPoseGPS = iniPoseVehicle+GPSPosOnVehicle;

	printf("Pose: %.6f,%.6f,%.6f", iniPoseGPS.x(),iniPoseGPS.y(),iniPoseGPS.z());
}
Esempio n. 5
0
	static void func_inv_compose_point(const CArrayDouble<6+3> &x, const double &dummy, CArrayDouble<3> &Y)
	{
		MRPT_UNUSED_PARAM(dummy);
		CPose3D q(x[0],x[1],x[2],x[3],x[4],x[5]);
		const CPoint3D 		p(x[6+0],x[6+1],x[6+2]);
		const CPoint3D pp = p-q;
		Y[0]=pp.x();
		Y[1]=pp.y();
		Y[2]=pp.z();
	}
Esempio n. 6
0
/*---------------------------------------------------------------
					drawSingleSample
 ---------------------------------------------------------------*/
void CPointPDFGaussian::drawSingleSample(CPoint3D &outSample) const
{
	MRPT_START

	vector_double vec;
	randomGenerator.drawGaussianMultivariate(vec,cov);

	ASSERT_(vec.size()==3);
	outSample.x( mean.x() + vec[0] );
	outSample.y( mean.y() + vec[1] );
	outSample.z( mean.z() + vec[2] );

	MRPT_END
}
Esempio n. 7
0
bool
CMathGeom3D::
TrianglesCentroid(CTriangle3D *triangles, int num_triangles, CPoint3D &cpoint)
{
  CPoint3D c;
  double   a, d = 0;

  cpoint.zero();

  for (int i = 0; i < num_triangles; ++i) {
    c = triangles[i].centroid();
    a = triangles[i].area2();

    cpoint += a*c;

    d += a;
  }

  if (fabs(d) < CMathGen::EPSILON_E6)
    return false;

  double id = 1.0/d;

  cpoint *= id;

  return true;
}
	void Pitch(float ang) {
		AngX += ang;
		
		CPoint3D rotDir = -(At - P0).Dir();
		At = P0 + (At - P0).RotateDeg(ang, Up);
		Up = Up.RotateDeg(ang, rotDir);
	}
	// angle in radians
	CPoint3D Rotate(float angle, CPoint3D dir) 
	{
		CPoint3D base = (*this) * cos(angle);
		CPoint3D elev = dir.Dir() * sin(angle);
		//cout << "orig = " + (*this).ToString() + ", base = " + base.ToString() + ", elev = " + elev.ToString() << "\n";
		return base + elev;
	}
Esempio n. 10
0
double poses_test_compose3Dpoint(int a1, int a2)
{
	const long N = 500000;
	CTicTac	 tictac;

	CPose3D   a(1.0,2.0,3.0,DEG2RAD(10),DEG2RAD(50),DEG2RAD(-30));
	CPoint3D  b(8.0,-5.0,-1.0);

	CPoint3D p;
	for (long i=0;i<N;i++)
	{
		p = a+b;
	}
	double T = tictac.Tac()/N;
	dummy_do_nothing_with_string( mrpt::format("%f",p.x()) );
	return T;
}
Esempio n. 11
0
CIntersectionInfo CTriangle::GetIntersection	(CRay ray)
{
	CPoint3D ptNoIntersection (0.0f, 0.0f, 0.0f, 0.0f);	// no intersection by default
	CPoint3D ptOfIntersection;
	CIntersectionInfo hitInfo;

	/***************************************************************
	STRATEGY:

	There are two major steps when trying to find the point of 
	intersection of a ray with a triangle, first to see if the ray
	intersects the plane of the triangle and then to see if the point
	on the plane that the ray intersects with lies within the triangle.

	So:
	1. Find the point of intersection on the triangle plane.
	2. Check if this point lies insdie the plane or not.
	3. Set the information into the hitInfo object.
	4. Return the hitInfo object.
	***************************************************************/

	// 1.
	ptOfIntersection = PlaneIntersect(ray);

	// 2.
	if ( !inTriangle(ptOfIntersection) || ptOfIntersection.AtInfinity()) {

		return hitInfo;
	}

	// 3.
	hitInfo.SetPointOfIntersection (ptOfIntersection);
	hitInfo.SetNormal (GetNormalAt(ptOfIntersection));
	hitInfo.SetColor(objColor);
	hitInfo.SetTexCoords (GetTexCoords(ptOfIntersection));

	// 4.
	return hitInfo;
}
Esempio n. 12
0
	void MoveCamera(int direction, float delta) {
		CPoint3D v;
		switch (direction){
		case BACK: delta = -delta;
		case FRONT:
			v = At - P0;
			v.Normalize();
			SetPosition(P0 + delta*v);
			SetDirection(At + delta*v); break;
		case LEFT: delta = -delta;
		case RIGHT:
			v = CrossProduct(At - P0, Up);
			v.Normalize();
			SetPosition(P0 + delta*v);
			SetDirection(At + delta*v); break;
		case DOWN: delta = -delta;
		case UP:
			v = Up;
			v.Normalize();
			SetPosition(P0 + delta*v);
			SetDirection(At + delta*v); break;
		}
		Update();
	}
Esempio n. 13
0
CRGBA
CRayMarbleTexture::
value(const CPoint3D &p) const
{
  double t1 = scale_*solid_noise_.turbulence(freq_*p, octaves_);

  double t = 2*fabs(sin(freq_*p.getX() + t1));

  if (t < 1)
    return t*c1_ + (1 - t)*c2_;
  else {
    t -= 1;

    return t*c0_ + (1 - t)*c1_;
  }
}
Esempio n. 14
0
void CSkeletonTracker::processPreviewNone()
{
		using namespace mrpt::opengl;

	// show laser scan
	if( m_showPreview )
	{
		if( !m_win )
		{
			string caption = string("Preview of ") + m_sensorLabel;
			m_win = mrpt::gui::CDisplayWindow3D::Create( caption, 800, 600 );
			
			COpenGLScenePtr & scene = m_win->get3DSceneAndLock();
			scene->insert( CGridPlaneXZ::Create(-3,3,0,5,-1.5 ) );
		
			// set camera parameters
			m_win->setCameraElevationDeg(-90);
			m_win->setCameraAzimuthDeg(90);
			m_win->setCameraZoom(4);
			m_win->setCameraPointingToPoint(0,0,0);
			
			// insert initial body
			CSetOfObjectsPtr body = CSetOfObjects::Create();
			body->setName("body");
			for(int i = 0; i < NUM_JOINTS; ++i)
			{
				CSpherePtr sph = CSphere::Create(0.03);
				sph->setColor(0,1,0);
				sph->setName( jointNames[i] );
				body->insert(sph);
			}
			
			// insert initial lines
			CSetOfLinesPtr lines = CSetOfLines::Create();
			lines->setName("lines");
			lines->setColor(0,0,1);
			body->insert(lines);
			
			scene->insert(body);
			m_win->unlockAccess3DScene();
		}

		if( m_win && m_win->isOpen() )
		{
			COpenGLScenePtr & scene = m_win->get3DSceneAndLock();
			{
				// update joints positions
				CSetOfObjectsPtr body = static_cast<CSetOfObjectsPtr>( scene->getByName("body") );
				ASSERT_( body )
							
				for(int i = 0; i < NUM_JOINTS; ++i)
				{
					CSpherePtr s = static_cast<CSpherePtr>( body->getByName( jointNames[i] ) );
					CPoint3D sphPos;
					if( i == 0 )
						sphPos = CPoint3D(0,0,0);
					else
					{
						m_joint_theta[i] += M_2PI/(10*(NUM_JOINTS-1));
						sphPos.x( 0.5*cos( m_joint_theta[i] ) );
						sphPos.y( 0.5*sin( m_joint_theta[i] ) );
						sphPos.z( 0.0 );
					}
					s->setPose( sphPos );
					s->setColor( 1, 0, 0 );
					s->setRadius( i == 0 ? 0.07 : 0.03 );
				} // end-for
			} // end-get3DSceneAndLock
			m_win->unlockAccess3DScene();
			m_win->forceRepaint();
		} // end if
	} // end if
Esempio n. 15
0
	void SetPosition(float x, float y, float z)
	{
		P0.Set(x, y, z);
	}
Esempio n. 16
0
void Run_KF_SLAM(CConfigFile& cfgFile, const std::string& rawlogFileName)
{
	// The EKF-SLAM class:
	// Traits for this KF implementation (2D or 3D)
	using traits_t = kfslam_traits<IMPL>;
	using ekfslam_t = typename traits_t::ekfslam_t;

	ekfslam_t mapping;

	// The rawlog file:
	// ----------------------------------------
	const unsigned int rawlog_offset =
		cfgFile.read_int("MappingApplication", "rawlog_offset", 0);

	const unsigned int SAVE_LOG_FREQUENCY =
		cfgFile.read_int("MappingApplication", "SAVE_LOG_FREQUENCY", 1);

	const bool SAVE_DA_LOG =
		cfgFile.read_bool("MappingApplication", "SAVE_DA_LOG", true);

	const bool SAVE_3D_SCENES =
		cfgFile.read_bool("MappingApplication", "SAVE_3D_SCENES", true);
	const bool SAVE_MAP_REPRESENTATIONS = cfgFile.read_bool(
		"MappingApplication", "SAVE_MAP_REPRESENTATIONS", true);
	bool SHOW_3D_LIVE =
		cfgFile.read_bool("MappingApplication", "SHOW_3D_LIVE", false);
	const bool CAMERA_3DSCENE_FOLLOWS_ROBOT = cfgFile.read_bool(
		"MappingApplication", "CAMERA_3DSCENE_FOLLOWS_ROBOT", false);

#if !MRPT_HAS_WXWIDGETS
	SHOW_3D_LIVE = false;
#endif

	string OUT_DIR = cfgFile.read_string(
		"MappingApplication", "logOutput_dir", "OUT_KF-SLAM");
	string ground_truth_file =
		cfgFile.read_string("MappingApplication", "ground_truth_file", "");
	string ground_truth_file_robot = cfgFile.read_string(
		"MappingApplication", "ground_truth_file_robot", "");

	string ground_truth_data_association = cfgFile.read_string(
		"MappingApplication", "ground_truth_data_association", "");

	cout << "RAWLOG FILE:" << endl << rawlogFileName << endl;
	ASSERT_FILE_EXISTS_(rawlogFileName);
	CFileGZInputStream rawlogFile(rawlogFileName);

	cout << "---------------------------------------------------" << endl
		 << endl;

	deleteFilesInDirectory(OUT_DIR);
	createDirectory(OUT_DIR);

	// Load the config options for mapping:
	// ----------------------------------------
	mapping.loadOptions(cfgFile);
	mapping.KF_options.dumpToConsole();
	mapping.options.dumpToConsole();

	// debug:
	// mapping.KF_options.use_analytic_observation_jacobian = true;
	// mapping.KF_options.use_analytic_transition_jacobian = true;
	// mapping.KF_options.debug_verify_analytic_jacobians = true;

	// Is there ground truth of the robot poses??
	CMatrixDouble GT_PATH(0, 0);
	if (ground_truth_file_robot.size() && fileExists(ground_truth_file_robot))
	{
		GT_PATH.loadFromTextFile(ground_truth_file_robot);
		ASSERT_(GT_PATH.rows() > 0 && GT_PATH.cols() == 6);
	}

	// Is there a ground truth file of the data association?
	std::map<double, std::vector<int>>
		GT_DA;  // Map: timestamp -> vector(index in observation -> real index)
	mrpt::containers::bimap<int, int> DA2GTDA_indices;  // Landmark indices
	// bimapping: SLAM DA <--->
	// GROUND TRUTH DA
	if (!ground_truth_data_association.empty() &&
		fileExists(ground_truth_data_association))
	{
		CMatrixDouble mGT_DA;
		mGT_DA.loadFromTextFile(ground_truth_data_association);
		ASSERT_ABOVEEQ_(mGT_DA.cols(), 3);
		// Convert the loaded matrix into a std::map in GT_DA:
		for (int i = 0; i < mGT_DA.rows(); i++)
		{
			std::vector<int>& v = GT_DA[mGT_DA(i, 0)];
			if (v.size() <= mGT_DA(i, 1)) v.resize(mGT_DA(i, 1) + 1);
			v[mGT_DA(i, 1)] = mGT_DA(i, 2);
		}
		cout << "Loaded " << GT_DA.size()
			 << " entries from DA ground truth file\n";
	}

	// Create output file for DA perf:
	std::ofstream out_da_performance_log;
	{
		const std::string f = std::string(
			OUT_DIR + std::string("/data_association_performance.log"));
		out_da_performance_log.open(f.c_str());
		ASSERTMSG_(
			out_da_performance_log.is_open(),
			std::string("Error writing to: ") + f);

		// Header:
		out_da_performance_log
			<< "%           TIMESTAMP                INDEX_IN_OBS    TruePos "
			   "FalsePos TrueNeg FalseNeg  NoGroundTruthSoIDontKnow \n"
			<< "%--------------------------------------------------------------"
			   "--------------------------------------------------\n";
	}

	if (SHOW_3D_LIVE)
	{
		win3d = mrpt::make_aligned_shared<mrpt::gui::CDisplayWindow3D>(
			"KF-SLAM live view", 800, 500);

		win3d->addTextMessage(
			0.01, 0.96, "Red: Estimated path", TColorf(0.8f, 0.8f, 0.8f), 100,
			MRPT_GLUT_BITMAP_HELVETICA_10);
		win3d->addTextMessage(
			0.01, 0.93, "Black: Ground truth path", TColorf(0.8f, 0.8f, 0.8f),
			101, MRPT_GLUT_BITMAP_HELVETICA_10);
	}

	// Create DA-log output file:
	std::ofstream out_da_log;
	if (SAVE_DA_LOG)
	{
		const std::string f =
			std::string(OUT_DIR + std::string("/data_association.log"));
		out_da_log.open(f.c_str());
		ASSERTMSG_(out_da_log.is_open(), std::string("Error writing to: ") + f);

		// Header:
		out_da_log << "%           TIMESTAMP                INDEX_IN_OBS    ID "
					  "   RANGE(m)    YAW(rad)   PITCH(rad) \n"
				   << "%-------------------------------------------------------"
					  "-------------------------------------\n";
	}

	// The main loop:
	// ---------------------------------------
	CActionCollection::Ptr action;
	CSensoryFrame::Ptr observations;
	size_t rawlogEntry = 0, step = 0;

	vector<TPose3D> meanPath;  // The estimated path
	typename traits_t::posepdf_t robotPose;
	const bool is_pose_3d = robotPose.state_length != 3;

	std::vector<typename IMPL::landmark_point_t> LMs;
	std::map<unsigned int, CLandmark::TLandmarkID> LM_IDs;
	CMatrixDouble fullCov;
	CVectorDouble fullState;
	CTicTac kftictac;

	auto rawlogArch = mrpt::serialization::archiveFrom(rawlogFile);

	for (;;)
	{
		if (os::kbhit())
		{
			char pushKey = os::getch();
			if (27 == pushKey) break;
		}

		// Load action/observation pair from the rawlog:
		// --------------------------------------------------
		if (!CRawlog::readActionObservationPair(
				rawlogArch, action, observations, rawlogEntry))
			break;  // file EOF

		if (rawlogEntry >= rawlog_offset)
		{
			// Process the action and observations:
			// --------------------------------------------
			kftictac.Tic();

			mapping.processActionObservation(action, observations);

			const double tim_kf_iter = kftictac.Tac();

			// Get current state:
			// -------------------------------
			mapping.getCurrentState(robotPose, LMs, LM_IDs, fullState, fullCov);
			cout << "Mean pose: " << endl << robotPose.mean << endl;
			cout << "# of landmarks in the map: " << LMs.size() << endl;

			// Get the mean robot pose as 3D:
			const CPose3D robotPoseMean3D = CPose3D(robotPose.mean);

			// Build the path:
			meanPath.push_back(robotPoseMean3D.asTPose());

			// Save mean pose:
			if (!(step % SAVE_LOG_FREQUENCY))
			{
				const auto p = robotPose.mean.asVectorVal();
				p.saveToTextFile(
					OUT_DIR +
					format("/robot_pose_%05u.txt", (unsigned int)step));
			}

			// Save full cov:
			if (!(step % SAVE_LOG_FREQUENCY))
			{
				fullCov.saveToTextFile(
					OUT_DIR + format("/full_cov_%05u.txt", (unsigned int)step));
			}

			// Generate Data Association log?
			if (SAVE_DA_LOG)
			{
				const typename ekfslam_t::TDataAssocInfo& da =
					mapping.getLastDataAssociation();

				const CObservationBearingRange::Ptr obs =
					observations
						->getObservationByClass<CObservationBearingRange>();
				if (obs)
				{
					const CObservationBearingRange* obsRB = obs.get();
					const double tim =
						mrpt::system::timestampToDouble(obsRB->timestamp);

					for (size_t i = 0; i < obsRB->sensedData.size(); i++)
					{
						auto it = da.results.associations.find(i);
						int assoc_ID_in_SLAM;
						if (it != da.results.associations.end())
							assoc_ID_in_SLAM = it->second;
						else
						{
							// It should be a newly created LM:
							auto itNewLM = da.newly_inserted_landmarks.find(i);
							if (itNewLM != da.newly_inserted_landmarks.end())
								assoc_ID_in_SLAM = itNewLM->second;
							else
								assoc_ID_in_SLAM = -1;
						}

						out_da_log << format(
							"%35.22f %8i %10i %10f %12f %12f\n", tim, (int)i,
							assoc_ID_in_SLAM,
							(double)obsRB->sensedData[i].range,
							(double)obsRB->sensedData[i].yaw,
							(double)obsRB->sensedData[i].pitch);
					}
				}
			}

			// Save report on DA performance:
			{
				const typename ekfslam_t::TDataAssocInfo& da =
					mapping.getLastDataAssociation();

				const CObservationBearingRange::Ptr obs =
					observations
						->getObservationByClass<CObservationBearingRange>();
				if (obs)
				{
					const CObservationBearingRange* obsRB = obs.get();
					const double tim =
						mrpt::system::timestampToDouble(obsRB->timestamp);

					auto itDA = GT_DA.find(tim);

					for (size_t i = 0; i < obsRB->sensedData.size(); i++)
					{
						bool is_FP = false, is_TP = false, is_FN = false,
							 is_TN = false;

						if (itDA != GT_DA.end())
						{
							const std::vector<int>& vDA = itDA->second;
							ASSERT_BELOW_(i, vDA.size());
							const int GT_ASSOC = vDA[i];

							auto it = da.results.associations.find(i);
							if (it != da.results.associations.end())
							{
								// This observation was assigned the already
								// existing LM in the map: "it->second"
								// TruePos -> If that LM index corresponds to
								// that in the GT (with index mapping):

								// mrpt::containers::bimap<int,int>
								// DA2GTDA_indices;
								// // Landmark indices bimapping: SLAM DA <--->
								// GROUND TRUTH DA
								if (DA2GTDA_indices.hasKey(it->second))
								{
									const int slam_asigned_LM_idx =
										DA2GTDA_indices.direct(it->second);
									if (slam_asigned_LM_idx == GT_ASSOC)
										is_TP = true;
									else
										is_FP = true;
								}
								else
								{
									// Is this case possible? Assigned to an
									// index not ever seen for the first time
									// with a GT....
									//  Just in case:
									is_FP = true;
								}
							}
							else
							{
								// No pairing, but should be a newly created LM:
								auto itNewLM =
									da.newly_inserted_landmarks.find(i);
								if (itNewLM !=
									da.newly_inserted_landmarks.end())
								{
									const int new_LM_in_SLAM = itNewLM->second;

									// Was this really a NEW LM not observed
									// before?
									if (DA2GTDA_indices.hasValue(GT_ASSOC))
									{
										// GT says this LM was already observed,
										// so it shouldn't appear here as new:
										is_FN = true;
									}
									else
									{
										// Really observed for the first time:
										is_TN = true;
										DA2GTDA_indices.insert(
											new_LM_in_SLAM, GT_ASSOC);
									}
								}
								else
								{
									// Not associated neither inserted:
									// Shouldn't really never arrive here.
								}
							}
						}

						// "%           TIMESTAMP                INDEX_IN_OBS
						// TruePos FalsePos TrueNeg FalseNeg
						// NoGroundTruthSoIDontKnow \n"
						out_da_performance_log << format(
							"%35.22f %13i %8i %8i %8i %8i %8i\n", tim, (int)i,
							(int)(is_TP ? 1 : 0), (int)(is_FP ? 1 : 0),
							(int)(is_TN ? 1 : 0), (int)(is_FN ? 1 : 0),
							(int)(!is_FP && !is_TP && !is_FN && !is_TN ? 1 : 0));
					}
				}
			}

			// Save map to file representations?
			if (SAVE_MAP_REPRESENTATIONS && !(step % SAVE_LOG_FREQUENCY))
			{
				mapping.saveMapAndPath2DRepresentationAsMATLABFile(
					OUT_DIR + format("/slam_state_%05u.m", (unsigned int)step));
			}

			// Save 3D view of the filter state:
			if (win3d || (SAVE_3D_SCENES && !(step % SAVE_LOG_FREQUENCY)))
			{
				COpenGLScene::Ptr scene3D =
					mrpt::make_aligned_shared<COpenGLScene>();
				{
					opengl::CGridPlaneXY::Ptr grid =
						mrpt::make_aligned_shared<opengl::CGridPlaneXY>(
							-1000, 1000, -1000, 1000, 0, 5);
					grid->setColor(0.4, 0.4, 0.4);
					scene3D->insert(grid);
				}

				// Robot path:
				{
					opengl::CSetOfLines::Ptr linesPath =
						mrpt::make_aligned_shared<opengl::CSetOfLines>();
					linesPath->setColor(1, 0, 0);

					TPose3D init_pose;
					if (!meanPath.empty())
						init_pose = CPose3D(meanPath[0]).asTPose();

					int path_decim = 0;
					for (auto& it : meanPath)
					{
						linesPath->appendLine(init_pose, it);
						init_pose = it;

						if (++path_decim > 10)
						{
							path_decim = 0;
							mrpt::opengl::CSetOfObjects::Ptr xyz =
								mrpt::opengl::stock_objects::CornerXYZSimple(
									0.3f, 2.0f);
							xyz->setPose(CPose3D(it));
							scene3D->insert(xyz);
						}
					}
					scene3D->insert(linesPath);

					// finally a big corner for the latest robot pose:
					{
						mrpt::opengl::CSetOfObjects::Ptr xyz =
							mrpt::opengl::stock_objects::CornerXYZSimple(
								1.0, 2.5);
						xyz->setPose(robotPoseMean3D);
						scene3D->insert(xyz);
					}

					// The camera pointing to the current robot pose:
					if (CAMERA_3DSCENE_FOLLOWS_ROBOT)
					{
						win3d->setCameraPointingToPoint(
							robotPoseMean3D.x(), robotPoseMean3D.y(),
							robotPoseMean3D.z());
					}
				}

				// Do we have a ground truth?
				if (GT_PATH.cols() == 6 || GT_PATH.cols() == 3)
				{
					opengl::CSetOfLines::Ptr GT_path =
						mrpt::make_aligned_shared<opengl::CSetOfLines>();
					GT_path->setColor(0, 0, 0);
					size_t N =
						std::min((int)GT_PATH.rows(), (int)meanPath.size());

					if (GT_PATH.cols() == 6)
					{
						double gtx0 = 0, gty0 = 0, gtz0 = 0;
						for (size_t i = 0; i < N; i++)
						{
							const CPose3D p(
								GT_PATH(i, 0), GT_PATH(i, 1), GT_PATH(i, 2),
								GT_PATH(i, 3), GT_PATH(i, 4), GT_PATH(i, 5));

							GT_path->appendLine(
								gtx0, gty0, gtz0, p.x(), p.y(), p.z());
							gtx0 = p.x();
							gty0 = p.y();
							gtz0 = p.z();
						}
					}
					else if (GT_PATH.cols() == 3)
					{
						double gtx0 = 0, gty0 = 0;
						for (size_t i = 0; i < N; i++)
						{
							const CPose2D p(
								GT_PATH(i, 0), GT_PATH(i, 1), GT_PATH(i, 2));

							GT_path->appendLine(gtx0, gty0, 0, p.x(), p.y(), 0);
							gtx0 = p.x();
							gty0 = p.y();
						}
					}
					scene3D->insert(GT_path);
				}

				// Draw latest data association:
				{
					const typename ekfslam_t::TDataAssocInfo& da =
						mapping.getLastDataAssociation();

					mrpt::opengl::CSetOfLines::Ptr lins =
						mrpt::make_aligned_shared<mrpt::opengl::CSetOfLines>();
					lins->setLineWidth(1.2f);
					lins->setColor(1, 1, 1);
					for (auto it = da.results.associations.begin();
						 it != da.results.associations.end(); ++it)
					{
						const prediction_index_t idxPred = it->second;
						// This index must match the internal list of features
						// in the map:
						typename ekfslam_t::KFArray_FEAT featMean;
						mapping.getLandmarkMean(idxPred, featMean);

						TPoint3D featMean3D;
						traits_t::landmark_to_3d(featMean, featMean3D);

						// Line: robot -> landmark:
						lins->appendLine(
							robotPoseMean3D.x(), robotPoseMean3D.y(),
							robotPoseMean3D.z(), featMean3D.x, featMean3D.y,
							featMean3D.z);
					}
					scene3D->insert(lins);
				}

				// The current state of KF-SLAM:
				{
					opengl::CSetOfObjects::Ptr objs =
						mrpt::make_aligned_shared<opengl::CSetOfObjects>();
					mapping.getAs3DObject(objs);
					scene3D->insert(objs);
				}

				if (win3d)
				{
					mrpt::opengl::COpenGLScene::Ptr& scn =
						win3d->get3DSceneAndLock();
					scn = scene3D;

					// Update text messages:
					win3d->addTextMessage(
						0.02, 0.02,
						format(
							"Step %u - Landmarks in the map: %u",
							(unsigned int)step, (unsigned int)LMs.size()),
						TColorf(1, 1, 1), 0, MRPT_GLUT_BITMAP_HELVETICA_12);

					win3d->addTextMessage(
						0.02, 0.06,
						format(
							is_pose_3d
								? "Estimated pose: (x y z qr qx qy qz) = %s"
								: "Estimated pose: (x y yaw) = %s",
							robotPose.mean.asString().c_str()),
						TColorf(1, 1, 1), 1, MRPT_GLUT_BITMAP_HELVETICA_12);

					static vector<double> estHz_vals;
					const double curHz = 1.0 / std::max(1e-9, tim_kf_iter);
					estHz_vals.push_back(curHz);
					if (estHz_vals.size() > 50)
						estHz_vals.erase(estHz_vals.begin());
					const double meanHz = mrpt::math::mean(estHz_vals);

					win3d->addTextMessage(
						0.02, 0.10,
						format(
							"Iteration time: %7ss",
							mrpt::system::unitsFormat(tim_kf_iter).c_str()),
						TColorf(1, 1, 1), 2, MRPT_GLUT_BITMAP_HELVETICA_12);

					win3d->addTextMessage(
						0.02, 0.14,
						format(
							"Execution rate: %7sHz",
							mrpt::system::unitsFormat(meanHz).c_str()),
						TColorf(1, 1, 1), 3, MRPT_GLUT_BITMAP_HELVETICA_12);

					win3d->unlockAccess3DScene();
					win3d->repaint();
				}

				if (SAVE_3D_SCENES && !(step % SAVE_LOG_FREQUENCY))
				{
					// Save to file:
					CFileGZOutputStream f(
						OUT_DIR +
						format("/kf_state_%05u.3Dscene", (unsigned int)step));
					mrpt::serialization::archiveFrom(f) << *scene3D;
				}
			}

			// Free rawlog items memory:
			// --------------------------------------------
			action.reset();
			observations.reset();

		}  // (rawlogEntry>=rawlog_offset)

		cout << format(
			"\nStep %u  - Rawlog entries processed: %i\n", (unsigned int)step,
			(unsigned int)rawlogEntry);

		step++;
	};  // end "while(1)"

	// Partitioning experiment: Only for 6D SLAM:
	traits_t::doPartitioningExperiment(mapping, fullCov, OUT_DIR);

	// Is there ground truth of landmarks positions??
	if (ground_truth_file.size() && fileExists(ground_truth_file))
	{
		CMatrixFloat GT(0, 0);
		try
		{
			GT.loadFromTextFile(ground_truth_file);
		}
		catch (const std::exception& e)
		{
			cerr << "Ignoring the following error loading ground truth file: "
				 << mrpt::exception_to_str(e) << endl;
		}

		if (GT.rows() > 0 && !LMs.empty())
		{
			// Each row has:
			//   [0] [1] [2]  [6]
			//    x   y   z    ID
			CVectorDouble ERRS(0);
			for (size_t i = 0; i < LMs.size(); i++)
			{
				// Find the entry in the GT for this mapped LM:
				bool found = false;
				for (int r = 0; r < GT.rows(); r++)
				{
					if (LM_IDs[i] == GT(r, 6))
					{
						const CPoint3D gtPt(GT(r, 0), GT(r, 1), GT(r, 2));
						ERRS.push_back(gtPt.distanceTo(
							CPoint3D(TPoint3D(LMs[i]))));  // All these
						// conversions
						// are to make it
						// work with
						// either
						// CPoint3D &
						// TPoint2D
						found = true;
						break;
					}
				}
				if (!found)
				{
					cerr << "Ground truth entry not found for landmark ID:"
						 << LM_IDs[i] << endl;
				}
			}

			printf("ERRORS VS. GROUND TRUTH:\n");
			printf("Mean Error: %f meters\n", math::mean(ERRS));
			printf("Minimum error: %f meters\n", math::minimum(ERRS));
			printf("Maximum error: %f meters\n", math::maximum(ERRS));
		}
	}  // end if GT

	cout << "********* KF-SLAM finished! **********" << endl;

	if (win3d)
	{
		cout << "\n Close the 3D window to quit the application.\n";
		win3d->waitForKey();
	}
}
Esempio n. 17
0
	void Set(float x0, float y0, float z0, float px0, float py0, float pz0, float upx, float upy, float upz)
	{
		P0.Set(x0, y0, z0); At.Set(px0, py0, pz0); Up.Set(upx, upy, upz); AngR = AngY = AngP = 0.0f;
	}
Esempio n. 18
0
void CIbeoLuxETH::dataCollection()
{
	unsigned char state = SearchForAF;
	unsigned char msgIn[1], Header[20], ScanListHeader[44], ScanPointData[10];
	unsigned int datatype, /*scannumber,*/ numScanpoints, angleTicks, SPlayer, SPdistance; // SPecho;
	int SPHangle;
	unsigned char msg[32];

	// Start TCP-connection to laserscanner
	m_client.connect(m_ip, m_port);

	// Send filter command
	makeCommandHeader(msg);
	makeTypeCommand(msg);
	m_client.writeAsync(&msg[0], 32);

	// Send start command
	makeCommandHeader(msg);
	makeStartCommand(msg);
	m_client.writeAsync(&msg[0], 28);

	while(m_run)
	{
		switch(state)
		{
			case SearchForAF:
				m_client.readAsync(msgIn, 1, 100, 10);
				if (msgIn[0] == 0xAF) state = SearchForFE;
				break;
			case SearchForFE:
				m_client.readAsync(msgIn, 1, 100, 10);
				if (msgIn[0] == 0xFE) state = SearchForC0; else state = SearchForAF;
				break;
			case SearchForC0:
				m_client.readAsync(msgIn, 1, 100, 10);
				if (msgIn[0] == 0xC0) state = SearchForC2; else state = SearchForAF;
				break;
			case SearchForC2:
				m_client.readAsync(msgIn, 1, 100, 10);
				if (msgIn[0] == 0xC2) state = PacketFound; else state = SearchForAF;
				break;
			case PacketFound:
				m_client.readAsync(Header, 20, 100, 10);
				datatype = Header[10] * 0x100 + Header[11];
				switch(datatype)
				{
					case 0x2030:
						// do nothing
						state = SearchForAF;
						break;
					case 0x2221:
						// do nothing
						state = SearchForAF;
						break;
					case 0x2805:
						// do nothing
						state = SearchForAF;
						break;
					case 0x2020:
						// do nothing
						state = SearchForAF;
						break;
					case 0x2202:
						state = SaveData;
						break;
					default:
						std::cerr << "UNKNOWN packet of type " << hex << datatype << " received!!\n";
						state = SearchForAF;
				}
				break;
			case SaveData:
				// Create new observation object pointer
				CObservation3DRangeScanPtr newObs = CObservation3DRangeScan::Create();
				newObs->hasPoints3D = true;
				newObs->maxRange = 200.00;

				m_client.readAsync(ScanListHeader, 44, 10, 10);
				/*scannumber =
				ScanListHeader[1] * 0x100 + ScanListHeader[0]; */
				numScanpoints = ScanListHeader[29] * 0x100 + ScanListHeader[28];
				angleTicks = ScanListHeader[23] * 0x100 + ScanListHeader[22];

				for (unsigned int i = 0; i < numScanpoints; ++i)
				{
					bool dropPacket = false;

					m_client.readAsync(ScanPointData, 10, 10, 10);
					SPlayer = ScanPointData[0] & 0x0F; // two lower bits denote layer
					// SPecho  = ScanPointData[0] >> 4; // two higher bits denote echo
					SPHangle = (char)ScanPointData[3] * 0x100 + ScanPointData[2]; // signed INT16 here
					SPdistance = ScanPointData[5] * 0x100 + ScanPointData[4];

					// Sanity checks
					if (SPlayer > 4)
					{
						dropPacket = true;
						//std::cerr << "Invalid layer: " << SPlayer << " should be element of [0,3] Scanpoint dropped.\n";
					}
					if ((SPHangle < -((int)angleTicks)/2) || (SPHangle > (int)angleTicks/2))
					{
						dropPacket = true;
						//std::cerr << "Invalid horizontal angle: " << (int)-angleTicks/2 << "< " << SPHangle << " <" << angleTicks/2 << " Scanpoint dropped.\n";
					}
					if ((SPdistance < 30) || (SPdistance > 20000))
					{
						dropPacket = true;
						//std::cerr << "Invalid distance: 30< " << SPdistance << " <20000 Scanpoint dropped.\n";
					}


					if (!dropPacket)
					{
						//TODO: Process point information correctly
						CPoint3D cartesianPoint = convertToCartesian(
							convertLayerToRad(SPlayer), // vertikal coord of scanner
							convertTicksToHRad(SPHangle, angleTicks), // horizontal coord of scanner
							SPdistance);

						// write scanpoint data to observation object
						newObs->points3D_x.push_back(cartesianPoint.x());
						newObs->points3D_y.push_back(cartesianPoint.y());
						newObs->points3D_z.push_back(cartesianPoint.z());
					}
				} // for

				// return observation to framework
				appendObservation( newObs );

				state = SearchForAF;
				break; // SaveData
		}	// Switch
	}	// While

	// Send stop command
	makeCommandHeader(msg);
	makeStopCommand(msg);
	m_client.writeAsync(&msg[0], 28);

	m_client.close();
}	// dataCollection
Esempio n. 19
0
	void SetDirection(float x, float y, float z)
	{
		At.Set(x, y, z);
	}
Esempio n. 20
0
	void Roll(float ang) {
		AngZ -= ang;

		Up = Up.RotateDeg(ang, Right());
	}
Esempio n. 21
0
void CBaseModel::AdjustScaleAndComputeNormalsToVerts()
{
	if (m_Verts.empty())
		return;
	m_NormalsToVerts.resize(m_Verts.size(), CPoint3D(0, 0, 0));
	CPoint3D center(0, 0, 0);
	double sumArea(0);
	CPoint3D sumNormal(0, 0, 0);
	double deta(0);
	for (int i = 0; i < (int)m_Faces.size(); ++i)
	{
		CPoint3D normal = VectorCross(Vert(Face(i)[0]),
			Vert(Face(i)[1]),
			Vert(Face(i)[2]));
		double area = normal.Len();
		CPoint3D gravity3 = Vert(Face(i)[0]) +	Vert(Face(i)[1]) + Vert(Face(i)[2]);
		center += area * gravity3;
		sumArea += area;
		sumNormal += normal;
		deta += gravity3 ^ normal;
		normal.x /= area;
		normal.y /= area;
		normal.z /= area;
		for (int j = 0; j < 3; ++j)
		{
			m_NormalsToVerts[Face(i)[j]] += normal;
		}
	}
	center /= sumArea * 3;
    fprintf(stderr,"center %lf %lf %lf\n" , center.x , center.y , center.z );
	deta -= 3 * (center ^ sumNormal);
	if (true)//deta > 0)
	{
		for (int i = 0; i < GetNumOfVerts(); ++i)
		{
			if (fabs(m_NormalsToVerts[i].x)
				+ fabs(m_NormalsToVerts[i].y)
				+ fabs(m_NormalsToVerts[i].z) >= FLT_EPSILON)
			{					
				m_NormalsToVerts[i].Normalize();
			}
		}
	}
	else
	{
		for (int i = 0; i < GetNumOfFaces(); ++i)
		{
			int temp = m_Faces[i][0];
			m_Faces[i][0] = m_Faces[i][1];
			m_Faces[i][1] = temp;
		}
		for (int i = 0; i < GetNumOfVerts(); ++i)
		{
			if (fabs(m_NormalsToVerts[i].x)
				+ fabs(m_NormalsToVerts[i].y)
				+ fabs(m_NormalsToVerts[i].z) >= FLT_EPSILON)
			{					
				double len = m_NormalsToVerts[i].Len();
				m_NormalsToVerts[i].x /= -len;
				m_NormalsToVerts[i].y /= -len;
				m_NormalsToVerts[i].z /= -len;
			}
		}
	}

	CPoint3D ptUp(m_Verts[0]);
	CPoint3D ptDown(m_Verts[0]);
	for (int i = 1; i < GetNumOfVerts(); ++i)
	{
		if (m_Verts[i].x > ptUp.x)
			ptUp.x = m_Verts[i].x;
		else if (m_Verts[i].x < ptDown.x)
			ptDown.x = m_Verts[i].x;
		if (m_Verts[i].y > ptUp.y)
			ptUp.y = m_Verts[i].y;
		else if (m_Verts[i].y < ptDown.y)
			ptDown.y = m_Verts[i].y;
		if (m_Verts[i].z > ptUp.z)
			ptUp.z = m_Verts[i].z;
		else if (m_Verts[i].z < ptDown.z)
			ptDown.z = m_Verts[i].z;
	}	

	double maxEdgeLenOfBoundingBox = -1;
	if (ptUp.x - ptDown.x > maxEdgeLenOfBoundingBox)
		maxEdgeLenOfBoundingBox = ptUp.x - ptDown.x;
	if (ptUp.y - ptDown.y > maxEdgeLenOfBoundingBox)
		maxEdgeLenOfBoundingBox = ptUp.y - ptDown.y;
	if (ptUp.z - ptDown.z > maxEdgeLenOfBoundingBox)
		maxEdgeLenOfBoundingBox = ptUp.z - ptDown.z;
	m_scale = 2.0 / maxEdgeLenOfBoundingBox;
	m_center = center;
	m_ptUp = ptUp;
	m_ptDown = ptDown;

	m_ptUp = (m_ptUp - center) * m_scale;
	m_ptDown = (m_ptUp - m_ptDown) * m_scale;
	//for (int i = 0; i < (int)m_Verts.size(); ++i)
	//{
	//	m_Verts[i] = (m_Verts[i] - center) * m_scale;
	//}

	m_scale = 1;
	m_center = CPoint3D(0, 0, 0);
}
Esempio n. 22
0
/*-------------------------------------------------------------
					processPreviewNone
-------------------------------------------------------------*/
void CSkeletonTracker::processPreviewNone()
{
	using namespace mrpt::opengl;

	// show skeleton data
	if( m_showPreview )
	{
		if( !m_win )
		{
			string caption = string("Preview of ") + m_sensorLabel;
			m_win = mrpt::gui::CDisplayWindow3D::Create( caption, 800, 600 );
			
			COpenGLScenePtr & scene = m_win->get3DSceneAndLock();
			scene->insert( CGridPlaneXZ::Create(-3,3,0,5,-1.5 ) );
		
			// set camera parameters
			m_win->setCameraElevationDeg(-90);
			m_win->setCameraAzimuthDeg(90);
			m_win->setCameraZoom(4);
			m_win->setCameraPointingToPoint(0,0,0);
			
			// insert initial body
			CSetOfObjectsPtr body = CSetOfObjects::Create();
			body->setName("body");
			for(int i = 0; i < NUM_JOINTS; ++i)
			{
				CSpherePtr sph = CSphere::Create(0.03f);
				sph->setColor(0,1,0);
				sph->setName( jointNames[i] );
				body->insert(sph);
			}
			
			// insert initial lines
			CSetOfLinesPtr lines = CSetOfLines::Create();
			lines->setName("lines");
			lines->setColor(0,0,1);
			body->insert(lines);
			
			scene->insert(body);
			m_win->unlockAccess3DScene();
		}

		if( m_win && m_win->isOpen() )
		{
			COpenGLScenePtr & scene = m_win->get3DSceneAndLock();
			{
				m_win->addTextMessage( 0.35, 0.9,
					"Please, adopt this position",
					TColorf(1,1,1),"mono",10, mrpt::opengl::FILL, 
					0);

				// insert translucid dummy and help text (it will go away when measurements are taken)
				if( !scene->getByName("dummy") ) 
				{
					const double SCALE			= 0.8;
					const double BODY_RADIUS	= 0.22*SCALE;
					const double BODY_LENGTH	= 0.8*SCALE;
					const double ARM_RADIUS		= 0.05*SCALE;
					const double ARM_LENGTH		= 0.4*SCALE;
					const double LEG_RADIUS		= 0.1*SCALE;
					const double LEG_LENGTH		= 0.8*SCALE;
					const double HEAD_RADIUS	= 0.15*SCALE;
					const double ALPHA_CH		= 0.8;
					
					CSetOfObjectsPtr dummy = CSetOfObjects::Create();
					dummy->setName("dummy");
					dummy->setPose(math::TPose3D(0,0,0,0,0,DEG2RAD(-90)));
					{
						// head
						CSpherePtr   part = CSphere::Create(HEAD_RADIUS);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(0,0,0.5*BODY_LENGTH+HEAD_RADIUS,0,0,0));
						dummy->insert(part);
					}
					{
						// body
						CCylinderPtr part = CCylinder::Create(BODY_RADIUS,BODY_RADIUS,BODY_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(0,0,-BODY_LENGTH/2,0,0,0));
						dummy->insert(part);
					}
					{
						// left arm 0
						CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(-BODY_RADIUS,0,0.5*BODY_LENGTH-ARM_RADIUS,0,DEG2RAD(-90),0));
						dummy->insert(part);
					}
					{
						// left arm 1
						CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(-BODY_RADIUS-ARM_LENGTH+ARM_RADIUS,0,0.5*BODY_LENGTH-ARM_RADIUS,0,0,0));
						dummy->insert(part);
					}
					{
						// right arm 0
						CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(BODY_RADIUS,0,0.5*BODY_LENGTH-ARM_RADIUS,0,DEG2RAD(90),0));
						dummy->insert(part);
					}
					{
						// right arm 1
						CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(BODY_RADIUS+ARM_LENGTH-ARM_RADIUS,0,0.5*BODY_LENGTH-ARM_RADIUS,0,0,0));
						dummy->insert(part);
					}
									{
						// left leg
						CCylinderPtr part = CCylinder::Create(LEG_RADIUS,LEG_RADIUS,LEG_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(-BODY_RADIUS+LEG_RADIUS,0,-(0.5*BODY_LENGTH+LEG_LENGTH),0,0,0));
						dummy->insert(part);
					}
					{
						// right leg
						CCylinderPtr part = CCylinder::Create(LEG_RADIUS,LEG_RADIUS,LEG_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(BODY_RADIUS-LEG_RADIUS,0,-(0.5*BODY_LENGTH+LEG_LENGTH),0,0,0));
						dummy->insert(part);
					}
					scene->insert(dummy);
				} // end-if
				else
				{
					CSetOfObjectsPtr dummy = static_cast<CSetOfObjectsPtr>( scene->getByName("dummy") );
					dummy->setVisibility(true);
				}

				// update joints positions
				CSetOfObjectsPtr body = static_cast<CSetOfObjectsPtr>( scene->getByName("body") );
				ASSERT_( body )
							
				for(int i = 0; i < NUM_JOINTS; ++i)
				{
					CSpherePtr s = static_cast<CSpherePtr>( body->getByName( jointNames[i] ) );
					CPoint3D sphPos;
					if( i == 0 )
						sphPos = CPoint3D(0,0,0);
					else
					{
						m_joint_theta[i] += M_2PI/(10*(NUM_JOINTS-1));
						sphPos.x( 0.5*cos( m_joint_theta[i] ) );
						sphPos.y( 0.5*sin( m_joint_theta[i] ) );
						sphPos.z( 0.0 );
					}
					s->setPose( sphPos );
					s->setColor( 1, 0, 0 );
					s->setRadius( i == 0 ? 0.07 : 0.03 );
				} // end-for
			} // end-get3DSceneAndLock
			m_win->unlockAccess3DScene();
			m_win->forceRepaint();
		} // end if
	} // end if
Esempio n. 23
0
void generateCylinder(CPoint3D start_p, CPoint3D end_p, vector<CPoint3D>& verts, vector<CBaseModel::CFace>& faces, double radius) 
{
	vector<CPoint3D> up_points;
	vector<CPoint3D> down_points;

	CPoint3D axis = (end_p - start_p).Normalize();
	CPoint3D p0_vec;
	if (axis.equal(CPoint3D(1,0,0))) {
		p0_vec = (axis * CPoint3D(0,0,1)).Normalize();
	}else{
		p0_vec = (axis * CPoint3D(1,0,0)).Normalize();
	}
	//printf("p0 %lf %lf %lf\n" , p0_vec.x, p0_vec.y, p0_vec.z);
	//p0_vec = radius * p0_vec;
	//printf("p0 %lf %lf %lf\n" , p0_vec.x, p0_vec.y, p0_vec.z);
	CPoint3D p4_vec = -1.0 * p0_vec;
	CPoint3D p6_vec = (axis * p0_vec).Normalize();
	CPoint3D p2_vec = -1.0 * p6_vec;
	CPoint3D p7_vec = (p0_vec + p6_vec).Normalize();
	CPoint3D p1_vec = (p0_vec + p2_vec).Normalize();
	CPoint3D p3_vec = (p2_vec + p4_vec).Normalize();
	CPoint3D p5_vec = (p4_vec + p6_vec).Normalize();

	//printf("p0 %lf %lf %lf\n" , p0_vec.x, p0_vec.y, p0_vec.z);
	//printf("p7 len %lf p0 len %lf\n" , p7_vec.Len(), p0_vec.Len());

	up_points.push_back(p0_vec);
	up_points.push_back(p1_vec);
	up_points.push_back(p2_vec );
	up_points.push_back(p3_vec );
	up_points.push_back(p4_vec );
	up_points.push_back(p5_vec );
	up_points.push_back(p6_vec );
	up_points.push_back(p7_vec );

	vector<CPoint3D> up_points_2;
	for (int i = 0; i < up_points.size(); ++i) {
		up_points_2.push_back(up_points[i]);
		CPoint3D p = (up_points[i] + up_points[(i+1)%up_points.size()]).Normalize();
		up_points_2.push_back(p);
	}
	swap(up_points, up_points_2);

	for (auto& p:up_points) {
		p *= radius;
		p += start_p;
	}

	for (auto& p:up_points) {
		down_points.push_back(p + end_p - start_p);
	}

	//FILE* file_cylinder = fopen("cylinder.obj", "w");
	//for (auto& p:up_points) {
	//	fprintf(file_cylinder, "v %lf %lf %lf\n" , p.x, p.y, p.z);
	//}
	//for (auto& p:down_points) {
	//	fprintf(file_cylinder, "v %lf %lf %lf\n" , p.x, p.y, p.z);
	//}
	//for (int i = 0; i < up_points.size(); ++i) {
	//	int up_v0 = i + 1;
	//	int up_v1 = (i+1)% up_points.size() + 1;
	//	int down_v0 = i + up_points.size() + 1;
	//	int down_v1 = (i+1)%up_points.size() + up_points.size() + 1;
	//	fprintf(file_cylinder, "f %d %d %d\n" , up_v0, down_v1, up_v1);
	//	fprintf(file_cylinder, "f %d %d %d\n" , up_v0, down_v0, down_v1);
	//}
	//fclose(file_cylinder);
	int verts_old_sz = verts.size();
	for (auto& p:up_points) {
		verts.push_back(p);
	}
	for (auto& p:down_points) {
		verts.push_back(p);
	}
	for (int i = 0; i < up_points.size(); ++i) {
		int up_v0 = verts_old_sz + i + 1;
		int up_v1 = verts_old_sz + (i+1) % up_points.size() + 1;
		int down_v0 = verts_old_sz + i + up_points.size() + 1;
		int down_v1 = verts_old_sz + (i+1) %up_points.size() + up_points.size() + 1;
		faces.push_back(CBaseModel::CFace(up_v0, down_v1, up_v1));
		faces.push_back(CBaseModel::CFace(up_v0, down_v0, down_v1));
	}

	//for (int i = 0; i < up_points.size(); ++i) {
	//	int up_v0 = i + 1;
	//	int up_v1 = (i+1)% up_points.size() + 1;
	//	int down_v0 = i + up_points.size() + 1;
	//	int down_v1 = (i+1)%up_points.size() + up_points.size() + 1;
	//	fprintf(file_cylinder, "f %d %d %d\n" , up_v0, down_v1, up_v1);
	//	fprintf(file_cylinder, "f %d %d %d\n" , up_v0, down_v0, down_v1);
	//}



}
Esempio n. 24
0
	string ToString()
	{
		return "P0 = " + P0.ToString() + ", At = " + At.ToString() + ", Up = " + Up.ToString() + ", dir = " + (At - P0).ToString();
	}
Esempio n. 25
0
	CCamera()
	{
		P0.Set(0.0f, 0.0f, 0.0f); At.Set(0.0f, 0.0f, 1.0f); Up.Set(0.0f, 1.0f, 0.0f); AngR = AngY = AngP = 0.0f;
	}
Esempio n. 26
0
CPose2D::CPose2D(const CPoint3D &o): m_phi(0),m_cossin_uptodate(false) {
	this->m_coords[0]	= o.x();
	this->m_coords[1]	= o.y();
	normalizePhi();
}
Esempio n. 27
0
CPoint3D xy2rgb(float x, float y) {
	CPoint3D rgb;
	hsv2rgb(x, y, 0.7, &rgb.x, &rgb.y, &rgb.z);
	rgb = rgb * (minf(0.8, rgb.Abs()) / rgb.Abs());
	return rgb;
}