<commit_before>#include <fstream>
#include <util/exceptions.h>
#include <util/Logger.h>
#include "GoldStandardFileReader.h"

logger::LogChannel goldstandardfilereaderlog("goldstandardfilereaderlog", "[GoldStandardFileReader] ");

GoldStandardFileReader::GoldStandardFileReader(const std::string& filename) :
		_filename(filename) {

	registerInput(_allSegments, "all segments");
	registerOutput(_goldStandard, "gold standard");
}

void
GoldStandardFileReader::updateOutputs() {

	// get the hashes of all gold-standard segments

	std::set<SegmentHash> goldStandardSegmentHashes;
	std::set<SegmentHash> otherSegmentHashes;

	std::ifstream file(_filename.c_str());

	if (!file.good()) {

		UTIL_THROW_EXCEPTION(
				UsageError,
				"could not open " << _filename << " to read the gold-standard hashes -- please make sure you created them beforehand!");
	}

	while (file.good()) {

		std::string line;
		std::getline(file, line);

		if (line.empty())
			continue;

		std::size_t hashStart = line.find_first_of('#');

		// is it a gold-standard segment? it is a gold-standard segment if there
		// is a '1' before the '#'
		std::size_t firstOne = line.find_first_of('1');
		bool isGoldStandard = (firstOne < hashStart);

		if (hashStart != std::string::npos) {

			std::string hashString = line.substr(hashStart);

			// strip any leading non-number
			std::size_t firstDigit = hashString.find_first_of("0123456789");
			hashString = hashString.substr(firstDigit);

			SegmentHash hash = boost::lexical_cast<SegmentHash>(hashString);

			if (isGoldStandard)
				goldStandardSegmentHashes.insert(hash);
			else
				otherSegmentHashes.insert(hash);

		} else {

			UTIL_THROW_EXCEPTION(
					UsageError,
					_filename << " does not contain a hash value in line '" << line << "'");
		}
	}

	// collect all gold-standard segments

	if (!_goldStandard)
		_goldStandard = new Segments();
	else
		_goldStandard->clear();

	foreach (boost::shared_ptr<EndSegment> segment, _allSegments->getEnds())
		if (goldStandardSegmentHashes.count(segment->hashValue()))
			_goldStandard->add(segment);
		else if (!otherSegmentHashes.count(segment->hashValue())) {

			LOG_ERROR(goldstandardfilereaderlog)
					<< "end segment " << segment->getId()
					<< " in ISI " << segment->getInterSectionInterval()
					<< " is not contained in "
					<< _filename << std::endl;
		}
	foreach (boost::shared_ptr<ContinuationSegment> segment, _allSegments->getContinuations())
		if (goldStandardSegmentHashes.count(segment->hashValue()))
			_goldStandard->add(segment);
		else if (!otherSegmentHashes.count(segment->hashValue())) {

			LOG_ERROR(goldstandardfilereaderlog)
					<< "continuation segment " << segment->getId()
					<< " in ISI " << segment->getInterSectionInterval()
					<< " is not contained in "
					<< _filename << std::endl;
		}
	foreach (boost::shared_ptr<BranchSegment> segment, _allSegments->getBranches())
		if (goldStandardSegmentHashes.count(segment->hashValue()))
			_goldStandard->add(segment);
		else if (!otherSegmentHashes.count(segment->hashValue())) {

			LOG_ERROR(goldstandardfilereaderlog)
					<< "branch segment " << segment->getId()
					<< " in ISI " << segment->getInterSectionInterval()
					<< " is not contained in "
					<< _filename << std::endl;
		}

	LOG_USER(goldstandardfilereaderlog)
			<< "collected " << _goldStandard->size()
			<< " segments in gold-standard" << std::endl;
}
<commit_msg>added end segments to first and last slices in GoldStandardFileReader to ensure consistent solution<commit_after>#include <fstream>
#include <util/exceptions.h>
#include <util/Logger.h>
#include "GoldStandardFileReader.h"

logger::LogChannel goldstandardfilereaderlog("goldstandardfilereaderlog", "[GoldStandardFileReader] ");

GoldStandardFileReader::GoldStandardFileReader(const std::string& filename) :
		_filename(filename) {

	registerInput(_allSegments, "all segments");
	registerOutput(_goldStandard, "gold standard");
}

void
GoldStandardFileReader::updateOutputs() {

	if (_allSegments->size() == 0)
		UTIL_THROW_EXCEPTION(
				UsageError,
				"given segment set is empty");

	// get the hashes of all gold-standard segments

	std::set<SegmentHash> goldStandardSegmentHashes;
	std::set<SegmentHash> otherSegmentHashes;

	std::ifstream file(_filename.c_str());

	if (!file.good()) {

		UTIL_THROW_EXCEPTION(
				UsageError,
				"could not open " << _filename << " to read the gold-standard hashes -- please make sure you created them beforehand!");
	}

	while (file.good()) {

		std::string line;
		std::getline(file, line);

		if (line.empty())
			continue;

		std::size_t hashStart = line.find_first_of('#');

		// is it a gold-standard segment? it is a gold-standard segment if there
		// is a '1' before the '#'
		std::size_t firstOne = line.find_first_of('1');
		bool isGoldStandard = (firstOne < hashStart);

		if (hashStart != std::string::npos) {

			std::string hashString = line.substr(hashStart);

			// strip any leading non-number
			std::size_t firstDigit = hashString.find_first_of("0123456789");
			hashString = hashString.substr(firstDigit);

			SegmentHash hash = boost::lexical_cast<SegmentHash>(hashString);

			if (isGoldStandard)
				goldStandardSegmentHashes.insert(hash);
			else
				otherSegmentHashes.insert(hash);

		} else {

			UTIL_THROW_EXCEPTION(
					UsageError,
					_filename << " does not contain a hash value in line '" << line << "'");
		}
	}

	// collect all gold-standard segments

	if (!_goldStandard)
		_goldStandard = new Segments();
	else
		_goldStandard->clear();

	foreach (boost::shared_ptr<EndSegment> segment, _allSegments->getEnds())
		if (goldStandardSegmentHashes.count(segment->hashValue()))
			_goldStandard->add(segment);
		else if (!otherSegmentHashes.count(segment->hashValue())) {

			LOG_ERROR(goldstandardfilereaderlog)
					<< "end segment " << segment->getId()
					<< " in ISI " << segment->getInterSectionInterval()
					<< " is not contained in "
					<< _filename << std::endl;
		}
	foreach (boost::shared_ptr<ContinuationSegment> segment, _allSegments->getContinuations())
		if (goldStandardSegmentHashes.count(segment->hashValue()))
			_goldStandard->add(segment);
		else if (!otherSegmentHashes.count(segment->hashValue())) {

			LOG_ERROR(goldstandardfilereaderlog)
					<< "continuation segment " << segment->getId()
					<< " in ISI " << segment->getInterSectionInterval()
					<< " is not contained in "
					<< _filename << std::endl;
		}
	foreach (boost::shared_ptr<BranchSegment> segment, _allSegments->getBranches())
		if (goldStandardSegmentHashes.count(segment->hashValue()))
			_goldStandard->add(segment);
		else if (!otherSegmentHashes.count(segment->hashValue())) {

			LOG_ERROR(goldstandardfilereaderlog)
					<< "branch segment " << segment->getId()
					<< " in ISI " << segment->getInterSectionInterval()
					<< " is not contained in "
					<< _filename << std::endl;
		}

	LOG_USER(goldstandardfilereaderlog)
			<< "collected " << _goldStandard->size()
			<< " segments in gold-standard" << std::endl;

	// make sure end segments are present for each slice in the first and last
	// section (this might not be the case if we are reading a subset of the
	// gold-standard)

	// get the first and last section number
	unsigned int firstSection = std::numeric_limits<unsigned int>::max();
	unsigned int lastSection  = 0;
	foreach (boost::shared_ptr<Segment> segment, _goldStandard->getSegments()) {
		foreach (boost::shared_ptr<Slice> slice, segment->getSlices()) {
			unsigned int section = slice->getSection();
			firstSection = std::min(firstSection, section);
			lastSection  = std::min(lastSection,  section);
		}
	}

	// collect all first and last slices
	std::set<boost::shared_ptr<Slice> > firstSlices;
	std::set<boost::shared_ptr<Slice> > lastSlices;
	foreach (boost::shared_ptr<Segment> segment, _goldStandard->getSegments()) {
		foreach (boost::shared_ptr<Slice> slice, segment->getSlices()) {

			if (slice->getSection() == firstSection)
				firstSlices.insert(slice);
			else if (slice->getSection() == lastSection)
				lastSlices.insert(slice);
		}
	}

	// get all end segments that use those slices (direction is determined by
	// providing the inter-section interval) and add them to the gold-standard
	foreach (boost::shared_ptr<EndSegment> firstEnd, _allSegments->getEnds(firstSection))
		if (firstSlices.count(firstEnd->getSlice()) > 0)
			_goldStandard->add(firstEnd);
	foreach (boost::shared_ptr<EndSegment> lastEnd, _allSegments->getEnds(lastSection + 1))
		if (lastSlices.count(lastEnd->getSlice()) > 0)
			_goldStandard->add(lastEnd);
}
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <Core/Algorithms/Math/SolveLinearSystemWithEigen.h>
#include <Core/Datatypes/DenseMatrix.h>
#include <Core/Datatypes/SparseRowMatrix.h>
#include <Core/Datatypes/MatrixTypeConversions.h>
#include <Eigen/Sparse>

using namespace SCIRun::Core::Algorithms::Math;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Algorithms;
using namespace SCIRun::Core;

namespace
{
  class SolveLinearSystemAlgorithmEigenCGImpl
  {
  public:
    SolveLinearSystemAlgorithmEigenCGImpl(const DenseColumnMatrix& rhs, double tolerance, int maxIterations) :
        rhs_(rhs), tolerance_(tolerance), maxIterations_(maxIterations) {}

    template <class MatrixType>
    DenseColumnMatrix solveWithEigen(const MatrixType& lhs)
    {
      Eigen::ConjugateGradient<typename MatrixType::EigenBase> cg;
      cg.compute(lhs);

      if (cg.info() != Eigen::Success)
        BOOST_THROW_EXCEPTION(AlgorithmInputException()
          << LinearAlgebraErrorMessage("Conjugate gradient initialization was unsuccessful")
          << EigenComputationInfo(cg.info()));

      cg.setTolerance(tolerance_);
      cg.setMaxIterations(maxIterations_);
      return cg.solve(rhs_);
    }
  private:
    const DenseColumnMatrix& rhs_;
    double tolerance_;
    int maxIterations_;
  };
}

SolveLinearSystemAlgorithm::Outputs SolveLinearSystemAlgorithm::run(const Inputs& input, const Parameters& params) const
{
  MatrixConstHandle A = input.get<0>();
  if (!A)
    BOOST_THROW_EXCEPTION(AlgorithmInputException() << NullObjectInfo("Null input matrix"));

  auto b = input.get<1>();
  if (!b)
    BOOST_THROW_EXCEPTION(AlgorithmInputException() << NullObjectInfo("Null rhs vector"));

  double tolerance = params.get<0>();
  if (tolerance < 0)
    BOOST_THROW_EXCEPTION(AlgorithmInputException() << DoubleOutOfRangeInfo(
      DoubleOutOfRangeInfo::value_type(
        std::string("Tolerance out of range!"),
        tolerance,
        boost::numeric::interval<double>(0, std::numeric_limits<double>::infinity()))));

  int maxIterations = params.get<1>();
  if (maxIterations < 0)
    BOOST_THROW_EXCEPTION(AlgorithmInputException() << IntOutOfRangeInfo(
      IntOutOfRangeInfo::value_type(
        std::string("Max iterations out of range!"),
        maxIterations,
         boost::numeric::interval<int>(0, std::numeric_limits<int>::infinity()))));

  SolveLinearSystemAlgorithmEigenCGImpl impl(*b, tolerance, maxIterations);
  DenseColumnMatrix x;
  if (matrix_is::dense(A))
    x = impl.solveWithEigen(*matrix_cast::as_dense(A));
  else if (matrix_is::sparse(A))
    x = impl.solveWithEigen(*matrix_cast::as_sparse(A));
  //TODO: move ctor
  if (x.size())
    return SolveLinearSystemAlgorithm::Outputs(new DenseColumnMatrix(x));
  else
    return SolveLinearSystemAlgorithm::Outputs();
}<commit_msg>Add TODO note. Closes #46.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <Core/Algorithms/Math/SolveLinearSystemWithEigen.h>
#include <Core/Datatypes/DenseMatrix.h>
#include <Core/Datatypes/SparseRowMatrix.h>
#include <Core/Datatypes/MatrixTypeConversions.h>
#include <Eigen/Sparse>

using namespace SCIRun::Core::Algorithms::Math;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Algorithms;
using namespace SCIRun::Core;

namespace
{
  class SolveLinearSystemAlgorithmEigenCGImpl
  {
  public:
    SolveLinearSystemAlgorithmEigenCGImpl(const DenseColumnMatrix& rhs, double tolerance, int maxIterations) :
        rhs_(rhs), tolerance_(tolerance), maxIterations_(maxIterations) {}

    template <class MatrixType>
    DenseColumnMatrix solveWithEigen(const MatrixType& lhs)
    {
      Eigen::ConjugateGradient<typename MatrixType::EigenBase> cg;
      cg.compute(lhs);

      if (cg.info() != Eigen::Success)
        BOOST_THROW_EXCEPTION(AlgorithmInputException()
          << LinearAlgebraErrorMessage("Conjugate gradient initialization was unsuccessful")
          << EigenComputationInfo(cg.info()));

      cg.setTolerance(tolerance_);
      cg.setMaxIterations(maxIterations_);
      return cg.solve(rhs_);
    }
  private:
    const DenseColumnMatrix& rhs_;
    double tolerance_;
    int maxIterations_;
  };
}

SolveLinearSystemAlgorithm::Outputs SolveLinearSystemAlgorithm::run(const Inputs& input, const Parameters& params) const
{
  //TODO: make convenience macros for these common error conditions (also to increase readability)
  MatrixConstHandle A = input.get<0>();
  if (!A)
    BOOST_THROW_EXCEPTION(AlgorithmInputException() << NullObjectInfo("Null input matrix"));

  auto b = input.get<1>();
  if (!b)
    BOOST_THROW_EXCEPTION(AlgorithmInputException() << NullObjectInfo("Null rhs vector"));

  double tolerance = params.get<0>();
  if (tolerance < 0)
    BOOST_THROW_EXCEPTION(AlgorithmInputException() << DoubleOutOfRangeInfo(
      DoubleOutOfRangeInfo::value_type(
        std::string("Tolerance out of range!"),
        tolerance,
        boost::numeric::interval<double>(0, std::numeric_limits<double>::infinity()))));

  int maxIterations = params.get<1>();
  if (maxIterations < 0)
    BOOST_THROW_EXCEPTION(AlgorithmInputException() << IntOutOfRangeInfo(
      IntOutOfRangeInfo::value_type(
        std::string("Max iterations out of range!"),
        maxIterations,
         boost::numeric::interval<int>(0, std::numeric_limits<int>::infinity()))));

  SolveLinearSystemAlgorithmEigenCGImpl impl(*b, tolerance, maxIterations);
  DenseColumnMatrix x;
  if (matrix_is::dense(A))
    x = impl.solveWithEigen(*matrix_cast::as_dense(A));
  else if (matrix_is::sparse(A))
    x = impl.solveWithEigen(*matrix_cast::as_sparse(A));
  //TODO: move ctor
  if (x.size())
    return SolveLinearSystemAlgorithm::Outputs(new DenseColumnMatrix(x));
  else
    return SolveLinearSystemAlgorithm::Outputs();
}<|endoftext|>


<commit_before>#ifndef __MATRIX_SR_CPP_
#define __MATRIX_SR_CPP_
#include "../../../include/tools/matrix/matrix_sr.h"
#include <iostream>
#include <cassert>
#include <cmath>
#include <complex> // std::complex, std::imag

#include "../../../include/tools/matrix/eigen_unsym.h"
#include "../../../include/tools/matrix/gaussj.h"

namespace matrix_sr {

	size_t_matrix_t matrix_multiplication(size_t_matrix_t m_k, size_t_matrix_t k_n) {
		std::size_t m = m_k.size();
		std::size_t m_k_k = m_k[0].size();
		std::size_t k_n_k = k_n.size();
		std::size_t n = k_n[0].size();
		// #columns of first matrix equals #rows of second matrix
		assert(m_k_k == k_n_k);

		size_t_matrix_t return_matrix(m, std::vector<rsp::index_int_t>(n, 0));

		for (std::size_t i = 0; i < m; ++i) {
			for (std::size_t j = 0; j < n; ++j) {
				return_matrix[i][j] = 0;
				for (std::size_t k = 0; k < m_k_k; ++k) {
					return_matrix[i][j] += m_k[i][k] * k_n[k][j];
				}
			}
		}

		return return_matrix;
	}

	size_t_matrix_t matrix_power(size_t_matrix_t n_n, std::size_t k)
	{
		if (k == 0)
			return size_t_matrix_t();
		assert(k >= 1);
		size_t_matrix_t A = n_n;
		for (std::size_t i = 0; i < k - 1; ++i) {
			A = matrix_multiplication(A, n_n);
		}

		return A;
	}

	path_R_matrix_t matrix_multiplication(path_R_matrix_t m_k, path_R_matrix_t k_n)
	{
		std::size_t m = m_k.size();
		std::size_t m_k_k = m_k[0].size();
		std::size_t k_n_k = k_n.size();
		std::size_t n = k_n[0].size();
		// #columns of first matrix equals #rows of second matrix
		assert(m_k_k == k_n_k);
		// each matrix element is a potential matrix
		path_R_matrix_t return_matrix(m, std::vector<path_R_matrix_element_t>(n));

		for (std::size_t i = 0; i < m; ++i) {
			for (std::size_t j = 0; j < n; ++j) {
				// define multiplication
				// combine two vectors into a single vector
				path_R_matrix_element_t p_new;
				for (std::size_t k = 0; k < m_k_k; ++k) {
					for (std::size_t l1 = 0; l1 < m_k[i][k].size(); ++l1) {
						// for all none-zero path, zero means no path, just a empty vector
						if (m_k[i][k][l1].size() != 0) {
							for (std::size_t l2 = 0; l2 < k_n[k][j].size(); ++l2) {
								if (k_n[k][j][l2].size() != 0) {
									std::vector<rsp::index_int_t> v_new;
									// combine two vectors
									v_new.reserve(m_k[i][k][l1].size() + k_n[k][j][l2].size()); // preallocate memory
									v_new.insert(v_new.end(), m_k[i][k][l1].begin(), m_k[i][k][l1].end());
									v_new.insert(v_new.end(), k_n[k][j][l2].begin(), k_n[k][j][l2].end());
									p_new.push_back(v_new);
								} // if
							} // l2

						} // if

					} // l1
				} // k

				if (p_new.size() == 0)
					p_new = {};
				return_matrix[i][j] = p_new;
			} // j
		} // i

		return return_matrix;
	}

	path_R_matrix_t matrix_power(path_R_matrix_t n_n, std::size_t k)
	{
		if (k == 0)
			return path_R_matrix_t();
		assert(k >= 1);
		path_R_matrix_t A = n_n;
		for (std::size_t i = 0; i < k - 1; ++i) {
			A = matrix_multiplication(A, n_n);
		}

		return A;

	}

	bool cal_equilibrium_ratio_from_transition_matrix(std::vector<std::vector<double>>& transition_mat, double &first_real_positive_eigenvalue, std::vector<double> &equil_ratio)
	{
		std::size_t m = transition_mat.size();
		equil_ratio.assign(m, 0.0);

		MatDoub mat_tmp(m, m, 0.0);
		for (std::size_t i = 0; i < m; ++i) {
			for (std::size_t j = 0; j < m; ++j) {
				mat_tmp[i][j] = transition_mat[i][j];
			}
		}

		Unsymmeig h(mat_tmp, true, true);
		auto eigen_val = h.wri;
		auto eigen_vec = h.zz;

		// find the first eigen value that's is positive
		// if there is more than one steady states, ignore the rest lol
		std::size_t first_real_idx = 0;
		bool ok = false;

		for (std::size_t i = 0; i < m; ++i) {
			if (eigen_val[i].imag() != 0)
				continue;
			// imaginary is zero, real number
			if (eigen_val[i].real() > 0) {
				first_real_idx = i;
				ok = true;
				break;
			}
		}

		// if there is no real positive eigen-value, return false
		if (ok == false)
			return false;

		first_real_positive_eigenvalue = eigen_val[first_real_idx].real();
		for (std::size_t i = 0; i < m; ++i) {
			//equil_ratio[i] = eigen_vec[i][first_real_idx];
			equil_ratio[i] = eigen_vec[i][first_real_idx] * eigen_vec[i][first_real_idx];
		}

		// normalize
		double sum_tmp = 0.0;
		for (std::size_t i = 0; i < m; ++i) {
			sum_tmp += equil_ratio[i];
		}
		if (sum_tmp == 0.0)
			return false;

		for (std::size_t i = 0; i < m; ++i) {
			equil_ratio[i] /= sum_tmp;
		}

		return true;
	}

	bool gaussian_jordan(std::vector<std::vector<double>>& A, std::vector<double> &b) {
		std::size_t m = A.size();
		//b.assign(m, 0.0);

		MatDoub A_mat(m, m, 0.0);
		for (std::size_t i = 0; i < m; ++i) {
			for (std::size_t j = 0; j < m; ++j) {
				A_mat[i][j] = A[i][j];
			}
		}

		MatDoub b_vec(m, 1, 0.0);
		for (std::size_t i = 0; i < m; ++i)
			b_vec[i][0] = b[i];

		auto ok = gaussj_return(A_mat, b_vec);

		std::size_t n_mat = A_mat.nrows() - 1;
		while (ok == false && (n_mat >= 1)) {

			// set the last variable to be 1.0, move the contribution from the varible to b vector
			MatDoub A_mat_tmp(n_mat, n_mat, 0.0);
			for (std::size_t i = 0; i < n_mat; ++i) {
				for (std::size_t j = 0; j < n_mat; ++j) {
					A_mat_tmp[i][j] = A[i][j];
				}
			}

			MatDoub b_vec_tmp(n_mat, 1, 0.0);
			for (std::size_t i = 0; i < n_mat; ++i)
				b_vec_tmp[i][0] = b[i];

			// set current the value of current b_vec to be 1.0, move the contribution of it to the b_vec
			b_vec[n_mat][0] = 1.0;
			for (std::size_t i = 0; i < n_mat; ++i)
				b_vec_tmp[i][0] -= (A[i][n_mat] * 1.0);

			ok = gaussj_return(A_mat_tmp, b_vec_tmp);

			if (ok == true) {
				for (std::size_t i = 0; i < n_mat; ++i)
					b_vec[i][0] = b_vec_tmp[i][0];
				break;
			}
			n_mat -= 1;
		}

		double sum_b = 0.0;
		if (ok == true) {
			for (std::size_t i = 0; i < m; ++i) {
				b[i] = b_vec[i][0];
				sum_b += b[i];
			}
		}

		// normalize
		if (ok == false || sum_b == 0) {
			for (std::size_t i = 0; i < m; ++i) {
				b[i] = 1.0 / m;
			}
		}
		else {
			for (std::size_t i = 0; i < m; ++i) {
				b[i] /= sum_b;
			}
		}

		return true;
	}

	//matrix_sr::size_t_matrix_t m1;
	//m1.resize(5);
	//m1[0] = { 0,1,1,1,1 };
	//m1[1] = { 0,0,1,1,1 };
	//m1[2] = { 0,0,0,1,1 };
	//m1[3] = { 0,0,0,0,1 };
	//m1[4] = { 0,0,0,0,0 };

	//matrix_sr::size_t_matrix_t m2 = matrix_sr::matrix_multiplication(m1, m1);

	//for (auto x : m2)
	//	std::cout << x << std::endl;

	//matrix_sr::size_t_matrix_t A = matrix_sr::matrix_power(m1, 2);
	//for (auto x : A)
	//	std::cout << x << std::endl;

	//matrix_sr::path_R_matrix_t m1;
	//m1.resize(5);
	//// each matrix element is a matrix
	//m1[0] = { {},{ { 1 } },{ { 2 } },{ { 3 } },{ { 4 } } };
	//m1[1] = { {},{},{ { 5 } },{ { 6 } },{ { 7 } } };
	//m1[2] = { {},{},{},{ { 8 } },{ { 9 } } };
	//m1[3] = { {},{},{},{},{ {10}, {11} } };
	//m1[4] = { {},{},{},{},{} };

	//for (std::size_t i = 0; i < m1.size(); ++i) {
	//	for (std::size_t j = 0; j < m1[i].size(); ++j) {
	//		std::cout << "(" << i << "," << j << ")\t";
	//		if (m1[i][j].size() == 0) {
	//			continue;
	//		}
	//		for (std::size_t k = 0; k < m1[i][j].size(); ++k) {
	//			for (std::size_t l = 0; l < m1[i][j][k].size(); ++l)
	//				std::cout << m1[i][j][k][l] << "\t";
	//		}
	//	}
	//	std::cout << std::endl;
	//}

	//matrix_sr::path_R_matrix_t m2 = matrix_sr::matrix_multiplication(m1, m1);

	//for (std::size_t i = 0; i < m2.size(); ++i) {
	//	for (std::size_t j = 0; j < m2[i].size(); ++j) {
	//		std::cout << "(" << i << "," << j << ")\t";
	//		if (m2[i][j].size() == 0) {
	//			continue;
	//		}
	//		for (std::size_t k = 0; k < m2[i][j].size(); ++k) {
	//			for (std::size_t l = 0; l < m2[i][j][k].size(); ++l)
	//				std::cout << m2[i][j][k][l] << "\t";
	//		}
	//	}
	//	std::cout << std::endl;
	//}

	//matrix_sr::path_R_matrix_t m3 = matrix_sr::matrix_power(m1, 3);

	//for (std::size_t i = 0; i < m3.size(); ++i) {
	//	for (std::size_t j = 0; j < m3[i].size(); ++j) {
	//		std::cout << "(" << i << "," << j << ")\t";
	//		if (m3[i][j].size() == 0) {
	//			continue;
	//		}
	//		for (std::size_t k = 0; k < m3[i][j].size(); ++k) {
	//			for (std::size_t l = 0; l < m3[i][j][k].size(); ++l)
	//				std::cout << m3[i][j][k][l] << "\t";
	//		}
	//	}
	//	std::cout << std::endl;
	//}

}

#endif // !__MATRIX_SR_CPP_
<commit_msg>minor<commit_after>#ifndef __MATRIX_SR_CPP_
#define __MATRIX_SR_CPP_
#include "../../../include/tools/matrix/matrix_sr.h"
#include <iostream>
#include <cassert>
#include <cmath>
#include <complex> // std::complex, std::imag

#include "../../../include/tools/matrix/eigen_unsym.h"
#include "../../../include/tools/matrix/gaussj.h"

namespace matrix_sr {

	size_t_matrix_t matrix_multiplication(size_t_matrix_t m_k, size_t_matrix_t k_n) {
		std::size_t m = m_k.size();
		std::size_t m_k_k = m_k[0].size();
		std::size_t k_n_k = k_n.size();
		std::size_t n = k_n[0].size();
		// #columns of first matrix equals #rows of second matrix
		assert(m_k_k == k_n_k);

		size_t_matrix_t return_matrix(m, std::vector<rsp::index_int_t>(n, 0));

		for (std::size_t i = 0; i < m; ++i) {
			for (std::size_t j = 0; j < n; ++j) {
				return_matrix[i][j] = 0;
				for (std::size_t k = 0; k < m_k_k; ++k) {
					return_matrix[i][j] += m_k[i][k] * k_n[k][j];
				}
			}
		}

		return return_matrix;
	}

	size_t_matrix_t matrix_power(size_t_matrix_t n_n, std::size_t k)
	{
		if (k == 0)
			return size_t_matrix_t();
		assert(k >= 1);
		size_t_matrix_t A = n_n;
		for (std::size_t i = 0; i < k - 1; ++i) {
			A = matrix_multiplication(A, n_n);
		}

		return A;
	}

	path_R_matrix_t matrix_multiplication(path_R_matrix_t m_k, path_R_matrix_t k_n)
	{
		std::size_t m = m_k.size();
		std::size_t m_k_k = m_k[0].size();
		std::size_t k_n_k = k_n.size();
		std::size_t n = k_n[0].size();
		// #columns of first matrix equals #rows of second matrix
		assert(m_k_k == k_n_k);
		// each matrix element is a potential matrix
		path_R_matrix_t return_matrix(m, std::vector<path_R_matrix_element_t>(n));

		for (std::size_t i = 0; i < m; ++i) {
			for (std::size_t j = 0; j < n; ++j) {
				// define multiplication
				// combine two vectors into a single vector
				path_R_matrix_element_t p_new;
				for (std::size_t k = 0; k < m_k_k; ++k) {
					for (std::size_t l1 = 0; l1 < m_k[i][k].size(); ++l1) {
						// for all none-zero path, zero means no path, just a empty vector
						if (m_k[i][k][l1].size() != 0) {
							for (std::size_t l2 = 0; l2 < k_n[k][j].size(); ++l2) {
								if (k_n[k][j][l2].size() != 0) {
									std::vector<rsp::index_int_t> v_new;
									// combine two vectors
									v_new.reserve(m_k[i][k][l1].size() + k_n[k][j][l2].size()); // preallocate memory
									v_new.insert(v_new.end(), m_k[i][k][l1].begin(), m_k[i][k][l1].end());
									v_new.insert(v_new.end(), k_n[k][j][l2].begin(), k_n[k][j][l2].end());
									p_new.push_back(v_new);
								} // if
							} // l2

						} // if

					} // l1
				} // k

				if (p_new.size() == 0)
					p_new = {};
				return_matrix[i][j] = p_new;
			} // j
		} // i

		return return_matrix;
	}

	path_R_matrix_t matrix_power(path_R_matrix_t n_n, std::size_t k)
	{
		if (k == 0)
			return path_R_matrix_t();
		assert(k >= 1);
		path_R_matrix_t A = n_n;
		for (std::size_t i = 0; i < k - 1; ++i) {
			A = matrix_multiplication(A, n_n);
		}

		return A;

	}

	bool cal_equilibrium_ratio_from_transition_matrix(std::vector<std::vector<double>>& transition_mat, double &first_real_positive_eigenvalue, std::vector<double> &equil_ratio)
	{
		std::size_t m = transition_mat.size();
		equil_ratio.assign(m, 0.0);

		MatDoub mat_tmp(m, m, 0.0);
		for (std::size_t i = 0; i < m; ++i) {
			for (std::size_t j = 0; j < m; ++j) {
				mat_tmp[i][j] = transition_mat[i][j];
			}
		}

		Unsymmeig h(mat_tmp, true, true);
		auto eigen_val = h.wri;
		auto eigen_vec = h.zz;

		// find the first eigen value that's is positive
		// if there is more than one steady states, ignore the rest lol
		std::size_t first_real_idx = 0;
		bool ok = false;

		for (std::size_t i = 0; i < m; ++i) {
			if (eigen_val[i].imag() != 0)
				continue;
			// imaginary is zero, real number
			if (eigen_val[i].real() > 0) {
				first_real_idx = i;
				ok = true;
				break;
			}
		}

		// if there is no real positive eigen-value, return false
		if (ok == false)
			return false;

		first_real_positive_eigenvalue = eigen_val[first_real_idx].real();
		for (std::size_t i = 0; i < m; ++i) {
			//equil_ratio[i] = eigen_vec[i][first_real_idx];
			equil_ratio[i] = eigen_vec[i][first_real_idx] * eigen_vec[i][first_real_idx];
		}

		// normalize
		double sum_tmp = 0.0;
		for (std::size_t i = 0; i < m; ++i) {
			sum_tmp += equil_ratio[i];
		}
		if (sum_tmp == 0.0)
			return false;

		for (std::size_t i = 0; i < m; ++i) {
			equil_ratio[i] /= sum_tmp;
		}

		return true;
	}

	bool gaussian_jordan(std::vector<std::vector<double>>& A, std::vector<double> &b) {
		std::size_t m = A.size();
		//b.assign(m, 0.0);

		MatDoub A_mat(m, m, 0.0);
		for (std::size_t i = 0; i < m; ++i) {
			for (std::size_t j = 0; j < m; ++j) {
				A_mat[i][j] = A[i][j];
			}
		}

		MatDoub b_vec(m, 1, 0.0);
		for (std::size_t i = 0; i < m; ++i)
			b_vec[i][0] = b[i];

		auto ok = gaussj_return(A_mat, b_vec);

		std::size_t n_mat = A_mat.nrows() - 1;
		while (ok == false && (n_mat >= 1)) {

			// set the last variable to be 1.0, move the contribution from the varible to b vector
			MatDoub A_mat_tmp(n_mat, n_mat, 0.0);
			for (std::size_t i = 0; i < n_mat; ++i) {
				for (std::size_t j = 0; j < n_mat; ++j) {
					A_mat_tmp[i][j] = A[i][j];
				}
			}

			MatDoub b_vec_tmp(n_mat, 1, 0.0);
			for (std::size_t i = 0; i < n_mat; ++i)
				b_vec_tmp[i][0] = b[i];

			// set current the value of current b_vec to be 1.0, move the contribution of it to the b_vec
			b_vec[n_mat][0] = 1.0;
			//for (std::size_t i = 0; i < n_mat; ++i)
			//	b_vec_tmp[i][0] -= (A[i][n_mat] * 1.0);
			for (std::size_t i = 0; i < n_mat; ++i) {
				for (std::size_t j = n_mat; j < m; ++j) {
					b_vec_tmp[i][0] -= (A[i][j] * 1.0);
				}
			}

			ok = gaussj_return(A_mat_tmp, b_vec_tmp);

			if (ok == true) {
				for (std::size_t i = 0; i < n_mat; ++i)
					b_vec[i][0] = b_vec_tmp[i][0];
				break;
			}
			n_mat -= 1;
		}

		double sum_b = 0.0;
		if (ok == true) {
			for (std::size_t i = 0; i < m; ++i) {
				b[i] = b_vec[i][0];
				sum_b += b[i];
			}
		}

		// normalize
		if (ok == false || sum_b == 0) {
			for (std::size_t i = 0; i < m; ++i) {
				b[i] = 1.0 / m;
			}
		}
		else {
			for (std::size_t i = 0; i < m; ++i) {
				b[i] /= sum_b;
			}
		}

		return true;
	}

	//matrix_sr::size_t_matrix_t m1;
	//m1.resize(5);
	//m1[0] = { 0,1,1,1,1 };
	//m1[1] = { 0,0,1,1,1 };
	//m1[2] = { 0,0,0,1,1 };
	//m1[3] = { 0,0,0,0,1 };
	//m1[4] = { 0,0,0,0,0 };

	//matrix_sr::size_t_matrix_t m2 = matrix_sr::matrix_multiplication(m1, m1);

	//for (auto x : m2)
	//	std::cout << x << std::endl;

	//matrix_sr::size_t_matrix_t A = matrix_sr::matrix_power(m1, 2);
	//for (auto x : A)
	//	std::cout << x << std::endl;

	//matrix_sr::path_R_matrix_t m1;
	//m1.resize(5);
	//// each matrix element is a matrix
	//m1[0] = { {},{ { 1 } },{ { 2 } },{ { 3 } },{ { 4 } } };
	//m1[1] = { {},{},{ { 5 } },{ { 6 } },{ { 7 } } };
	//m1[2] = { {},{},{},{ { 8 } },{ { 9 } } };
	//m1[3] = { {},{},{},{},{ {10}, {11} } };
	//m1[4] = { {},{},{},{},{} };

	//for (std::size_t i = 0; i < m1.size(); ++i) {
	//	for (std::size_t j = 0; j < m1[i].size(); ++j) {
	//		std::cout << "(" << i << "," << j << ")\t";
	//		if (m1[i][j].size() == 0) {
	//			continue;
	//		}
	//		for (std::size_t k = 0; k < m1[i][j].size(); ++k) {
	//			for (std::size_t l = 0; l < m1[i][j][k].size(); ++l)
	//				std::cout << m1[i][j][k][l] << "\t";
	//		}
	//	}
	//	std::cout << std::endl;
	//}

	//matrix_sr::path_R_matrix_t m2 = matrix_sr::matrix_multiplication(m1, m1);

	//for (std::size_t i = 0; i < m2.size(); ++i) {
	//	for (std::size_t j = 0; j < m2[i].size(); ++j) {
	//		std::cout << "(" << i << "," << j << ")\t";
	//		if (m2[i][j].size() == 0) {
	//			continue;
	//		}
	//		for (std::size_t k = 0; k < m2[i][j].size(); ++k) {
	//			for (std::size_t l = 0; l < m2[i][j][k].size(); ++l)
	//				std::cout << m2[i][j][k][l] << "\t";
	//		}
	//	}
	//	std::cout << std::endl;
	//}

	//matrix_sr::path_R_matrix_t m3 = matrix_sr::matrix_power(m1, 3);

	//for (std::size_t i = 0; i < m3.size(); ++i) {
	//	for (std::size_t j = 0; j < m3[i].size(); ++j) {
	//		std::cout << "(" << i << "," << j << ")\t";
	//		if (m3[i][j].size() == 0) {
	//			continue;
	//		}
	//		for (std::size_t k = 0; k < m3[i][j].size(); ++k) {
	//			for (std::size_t l = 0; l < m3[i][j][k].size(); ++l)
	//				std::cout << m3[i][j][k][l] << "\t";
	//		}
	//	}
	//	std::cout << std::endl;
	//}

}

#endif // !__MATRIX_SR_CPP_
<|endoftext|>


<commit_before>#include "QGCWaypointListMulti.h"
#include "ui_QGCWaypointListMulti.h"
#include "UASManager.h"

QGCWaypointListMulti::QGCWaypointListMulti(QWidget *parent) :
    QWidget(parent),
    offline_uas_id(0),
    ui(new Ui::QGCWaypointListMulti)
{
    ui->setupUi(this);
    setMinimumSize(600, 80);
    connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(systemCreated(UASInterface*)));
    connect(UASManager::instance(), SIGNAL(activeUASSet(int)), this, SLOT(systemSetActive(int)));

    WaypointList* list = new WaypointList(ui->stackedWidget, UASManager::instance()->getActiveUASWaypointManager());
    lists.insert(offline_uas_id, list);
    ui->stackedWidget->addWidget(list);

    if (UASManager::instance()->getActiveUAS()) {
        systemCreated(UASManager::instance()->getActiveUAS());
        systemSetActive(UASManager::instance()->getActiveUAS()->getUASID());
    }

}

void QGCWaypointListMulti::systemDeleted(QObject* uas)
{
    UASInterface* mav = dynamic_cast<UASInterface*>(uas);
    if (mav)
    {
        int id = mav->getUASID();
        WaypointList* list = lists.value(id, NULL);
        if (list)
        {
            delete list;
            lists.remove(id);
        }
    }
}

void QGCWaypointListMulti::systemCreated(UASInterface* uas)
{
    WaypointList* list = new WaypointList(ui->stackedWidget, uas->getWaypointManager());
    lists.insert(uas->getUASID(), list);
    ui->stackedWidget->addWidget(list);
    // Ensure widget is deleted when system is deleted
    connect(uas, SIGNAL(destroyed(QObject*)), this, SLOT(systemDeleted(QObject*)));
}

void QGCWaypointListMulti::systemSetActive(int uas)
{
    WaypointList* list = lists.value(uas, NULL);
    if (list) {
        ui->stackedWidget->setCurrentWidget(list);
    }
}

QGCWaypointListMulti::~QGCWaypointListMulti()
{
    delete ui;
}

void QGCWaypointListMulti::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
<commit_msg>Fix to Waypoint Edit Widget being to small<commit_after>#include "QGCWaypointListMulti.h"
#include "ui_QGCWaypointListMulti.h"
#include "UASManager.h"

QGCWaypointListMulti::QGCWaypointListMulti(QWidget *parent) :
    QWidget(parent),
    offline_uas_id(0),
    ui(new Ui::QGCWaypointListMulti)
{
    ui->setupUi(this);
    setMinimumSize(600, 120);
    connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(systemCreated(UASInterface*)));
    connect(UASManager::instance(), SIGNAL(activeUASSet(int)), this, SLOT(systemSetActive(int)));

    WaypointList* list = new WaypointList(ui->stackedWidget, UASManager::instance()->getActiveUASWaypointManager());
    lists.insert(offline_uas_id, list);
    ui->stackedWidget->addWidget(list);

    if (UASManager::instance()->getActiveUAS()) {
        systemCreated(UASManager::instance()->getActiveUAS());
        systemSetActive(UASManager::instance()->getActiveUAS()->getUASID());
    }

}

void QGCWaypointListMulti::systemDeleted(QObject* uas)
{
    UASInterface* mav = dynamic_cast<UASInterface*>(uas);
    if (mav)
    {
        int id = mav->getUASID();
        WaypointList* list = lists.value(id, NULL);
        if (list)
        {
            delete list;
            lists.remove(id);
        }
    }
}

void QGCWaypointListMulti::systemCreated(UASInterface* uas)
{
    WaypointList* list = new WaypointList(ui->stackedWidget, uas->getWaypointManager());
    lists.insert(uas->getUASID(), list);
    ui->stackedWidget->addWidget(list);
    // Ensure widget is deleted when system is deleted
    connect(uas, SIGNAL(destroyed(QObject*)), this, SLOT(systemDeleted(QObject*)));
}

void QGCWaypointListMulti::systemSetActive(int uas)
{
    WaypointList* list = lists.value(uas, NULL);
    if (list) {
        ui->stackedWidget->setCurrentWidget(list);
    }
}

QGCWaypointListMulti::~QGCWaypointListMulti()
{
    delete ui;
}

void QGCWaypointListMulti::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osg/DisplaySettings>
#include <osg/ArgumentParser>
#include <osg/ApplicationUsage>
#include <osg/ref_ptr>

#include <algorithm>

using namespace osg;
using namespace std;

DisplaySettings* DisplaySettings::instance()
{
    static ref_ptr<DisplaySettings> s_displaySettings = new DisplaySettings;
    return s_displaySettings.get();
}

DisplaySettings::DisplaySettings(const DisplaySettings& vs):Referenced()
{
    setDisplaySettings(vs);
}

DisplaySettings::~DisplaySettings()
{
}

 DisplaySettings& DisplaySettings::operator = (const DisplaySettings& vs)
{
    if (this==&vs) return *this;
    setDisplaySettings(vs);
    return *this;
}

void DisplaySettings::setDisplaySettings(const DisplaySettings& vs)
{
    _displayType = vs._displayType;
    _stereoMode = vs._stereoMode;
    _eyeSeparation = vs._eyeSeparation;
    _screenWidth = vs._screenWidth;
    _screenHeight = vs._screenHeight;
    _screenDistance = vs._screenDistance;

    _splitStereoHorizontalEyeMapping = vs._splitStereoHorizontalEyeMapping;
    _splitStereoHorizontalSeparation = vs._splitStereoHorizontalSeparation;

    _splitStereoVerticalEyeMapping = vs._splitStereoVerticalEyeMapping;
    _splitStereoVerticalSeparation = vs._splitStereoVerticalSeparation;

    _splitStereoAutoAdjustAspectRatio = vs._splitStereoAutoAdjustAspectRatio;

    _doubleBuffer = vs._doubleBuffer;
    _RGB = vs._RGB;
    _depthBuffer = vs._depthBuffer;
    _minimumNumberAlphaBits = vs._minimumNumberAlphaBits;
    _minimumNumberStencilBits = vs._minimumNumberStencilBits;

    _maxNumOfGraphicsContexts = vs._maxNumOfGraphicsContexts;
}

void DisplaySettings::merge(const DisplaySettings& vs)
{
    if (_stereo       || vs._stereo)        _stereo = true;

    // need to think what to do about merging the stereo mode.

    if (_doubleBuffer || vs._doubleBuffer)  _doubleBuffer = true;
    if (_RGB          || vs._RGB)           _RGB = true;
    if (_depthBuffer  || vs._depthBuffer)   _depthBuffer = true;

    if (vs._minimumNumberAlphaBits>_minimumNumberAlphaBits) _minimumNumberAlphaBits = vs._minimumNumberAlphaBits;
    if (vs._minimumNumberStencilBits>_minimumNumberStencilBits) _minimumNumberStencilBits = vs._minimumNumberStencilBits;
}

void DisplaySettings::setDefaults()
{
    _displayType = MONITOR;

    _stereo = false;
    _stereoMode = ANAGLYPHIC;
    _eyeSeparation = 0.05f;
    _screenWidth = 0.325f;
    _screenHeight = 0.26f;
    _screenDistance = 0.5f;

    _splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT;
    _splitStereoHorizontalSeparation = 0;

    _splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT;
    _splitStereoVerticalSeparation = 0;

    _splitStereoAutoAdjustAspectRatio = true;

    _doubleBuffer = true;
    _RGB = true;
    _depthBuffer = true;
    _minimumNumberAlphaBits = 0;
    _minimumNumberStencilBits = 0;

    _maxNumOfGraphicsContexts = 3;
}

static ApplicationUsageProxy DisplaySetting_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_DISPLAY_TYPE <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY");
static ApplicationUsageProxy DisplaySetting_e1(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO_MODE <mode>","QUAD_BUFFER | ANAGLYPHIC | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE");
static ApplicationUsageProxy DisplaySetting_e2(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO <mode>","OFF | ON");
static ApplicationUsageProxy DisplaySetting_e3(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_EYE_SEPARATION <float>","physical distance between eyes");
static ApplicationUsageProxy DisplaySetting_e4(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_DISTANCE <float>","physical distance between eyes and screen");
static ApplicationUsageProxy DisplaySetting_e5(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_HEIGHT <float>","physical screen height");
static ApplicationUsageProxy DisplaySetting_e6(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_WIDTH <float>","physical screen width");
static ApplicationUsageProxy DisplaySetting_e7(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING <mode>","LEFT_EYE_LEFT_VIEWPORT | LEFT_EYE_RIGHT_VIEWPORT");
static ApplicationUsageProxy DisplaySetting_e8(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION <float>","number of pixels between viewports");
static ApplicationUsageProxy DisplaySetting_e9(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING <mode>","LEFT_EYE_TOP_VIEWPORT | LEFT_EYE_BOTTOM_VIEWPORT");
static ApplicationUsageProxy DisplaySetting_e10(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO <mode>","OFF | ON  Default to ON to compenstate for the compression of the aspect ratio when viewing in split screen stereo.  Note, if you are setting fovx and fovy explicityly OFF should be used.");
static ApplicationUsageProxy DisplaySetting_e11(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_SEPARATION <float>","number of pixels between viewports");
static ApplicationUsageProxy DisplaySetting_e12(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS <int>","maximum number of graphics contexts to be used with applications.");

void DisplaySettings::readEnvironmentalVariables()
{
    char *ptr;

    if ((ptr = getenv("OSG_DISPLAY_TYPE")) != 0)
    {
        if (strcmp(ptr,"MONITOR")==0)
        {
            _displayType = MONITOR;
        }
        else
        if (strcmp(ptr,"POWERWALL")==0)
        {
            _displayType = POWERWALL;
        }
        else
        if (strcmp(ptr,"REALITY_CENTER")==0)
        {
            _displayType = REALITY_CENTER;
        }
        else
        if (strcmp(ptr,"HEAD_MOUNTED_DISPLAY")==0)
        {
            _displayType = HEAD_MOUNTED_DISPLAY;
        }
    }

    if( (ptr = getenv("OSG_STEREO_MODE")) != 0)
    {
        if (strcmp(ptr,"QUAD_BUFFER")==0)
        {
            _stereoMode = QUAD_BUFFER;
        }
        else
        if (strcmp(ptr,"ANAGLYPHIC")==0)
        {
            _stereoMode = ANAGLYPHIC;
        }
        else
        if (strcmp(ptr,"HORIZONTAL_SPLIT")==0)
        {
            _stereoMode = HORIZONTAL_SPLIT;
        }
        else
        if (strcmp(ptr,"VERTICAL_SPLIT")==0)
        {
            _stereoMode = VERTICAL_SPLIT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE")==0)
        {
            _stereoMode = LEFT_EYE;
        }
        else
        if (strcmp(ptr,"RIGHT_EYE")==0)
        {
            _stereoMode = RIGHT_EYE;
        }
    }

    if( (ptr = getenv("OSG_STEREO")) != 0)
    {
        if (strcmp(ptr,"OFF")==0)
        {
            _stereo = false;
        }
        else
        if (strcmp(ptr,"ON")==0)
        {
            _stereo = true;
        }
    }

    if( (ptr = getenv("OSG_EYE_SEPARATION")) != 0)
    {
        _eyeSeparation = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_WIDTH")) != 0)
    {
        _screenWidth = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_HEIGHT")) != 0)
    {
        _screenHeight = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_DISTANCE")) != 0)
    {
        _screenDistance = atof(ptr);
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING")) != 0)
    {
        if (strcmp(ptr,"LEFT_EYE_LEFT_VIEWPORT")==0)
        {
            _splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE_RIGHT_VIEWPORT")==0)
        {
            _splitStereoHorizontalEyeMapping = LEFT_EYE_RIGHT_VIEWPORT;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION")) != 0)
    {
        _splitStereoHorizontalSeparation = atoi(ptr);
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING")) != 0)
    {
        if (strcmp(ptr,"LEFT_EYE_TOP_VIEWPORT")==0)
        {
            _splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE_BOTTOM_VIEWPORT")==0)
        {
            _splitStereoVerticalEyeMapping = LEFT_EYE_BOTTOM_VIEWPORT;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO")) != 0)
    {
        if (strcmp(ptr,"OFF")==0)
        {
            _splitStereoAutoAdjustAspectRatio = false;
        }
        else
        if (strcmp(ptr,"ON")==0)
        {
            _splitStereoAutoAdjustAspectRatio = true;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_VERTICAL_SEPARATION")) != 0)
    {
        _splitStereoVerticalSeparation = atoi(ptr);
    }

    if( (ptr = getenv("OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS")) != 0)
    {
        _maxNumOfGraphicsContexts = atoi(ptr);
    }
}

void DisplaySettings::readCommandLine(ArgumentParser& arguments)
{

    // report the usage options.
    if (arguments.getApplicationUsage())
    {
        arguments.getApplicationUsage()->addCommandLineOption("--display <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY");
        arguments.getApplicationUsage()->addCommandLineOption("--stereo","Use default stereo mode which is ANAGLYPHIC if not overriden by environmental variable");
        arguments.getApplicationUsage()->addCommandLineOption("--stereo <mode>","ANAGLYPHIC | QUAD_BUFFER | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE | ON | OFF ");
        arguments.getApplicationUsage()->addCommandLineOption("--rgba","Request a RGBA color buffer visual");
        arguments.getApplicationUsage()->addCommandLineOption("--stencil","Request a stencil buffer visual");
    }

    std::string str;
    while(arguments.read("--display",str))
    {
        if (str=="MONITOR") _displayType = MONITOR;
        else if (str=="POWERWALL") _displayType = POWERWALL;
        else if (str=="REALITY_CENTER") _displayType = REALITY_CENTER;
        else if (str=="HEAD_MOUNTED_DISPLAY") _displayType = HEAD_MOUNTED_DISPLAY;
    }

    int pos;
    while ((pos=arguments.find("--stereo"))!=0)
    {
        if (arguments.match(pos+1,"ANAGLYPHIC"))            { arguments.remove(pos,2); _stereo = true;_stereoMode = ANAGLYPHIC; }
        else if (arguments.match(pos+1,"QUAD_BUFFER"))      { arguments.remove(pos,2); _stereo = true;_stereoMode = QUAD_BUFFER; }
        else if (arguments.match(pos+1,"HORIZONTAL_SPLIT")) { arguments.remove(pos,2); _stereo = true;_stereoMode = HORIZONTAL_SPLIT; }
        else if (arguments.match(pos+1,"VERTICAL_SPLIT"))   { arguments.remove(pos,2); _stereo = true;_stereoMode = VERTICAL_SPLIT; }
        else if (arguments.match(pos+1,"LEFT_EYE"))         { arguments.remove(pos,2); _stereo = true;_stereoMode = LEFT_EYE; }
        else if (arguments.match(pos+1,"RIGHT_EYE"))        { arguments.remove(pos,2); _stereo = true;_stereoMode = RIGHT_EYE; }
        else if (arguments.match(pos+1,"ON"))               { arguments.remove(pos,2); _stereo = true; }
        else if (arguments.match(pos+1,"OFF"))              { arguments.remove(pos,2); _stereo = false; }
        else                                                { arguments.remove(pos); _stereo = true; }
    }

    while (arguments.read("--rgba"))
    {
        _RGB = true;
        _minimumNumberAlphaBits = 1;
    }

    while (arguments.read("--stencil"))
    {
        _minimumNumberStencilBits = 1;
    }
}
<commit_msg>Added missing copy of _stereo<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osg/DisplaySettings>
#include <osg/ArgumentParser>
#include <osg/ApplicationUsage>
#include <osg/ref_ptr>

#include <algorithm>

using namespace osg;
using namespace std;

DisplaySettings* DisplaySettings::instance()
{
    static ref_ptr<DisplaySettings> s_displaySettings = new DisplaySettings;
    return s_displaySettings.get();
}

DisplaySettings::DisplaySettings(const DisplaySettings& vs):Referenced()
{
    setDisplaySettings(vs);
}

DisplaySettings::~DisplaySettings()
{
}

 DisplaySettings& DisplaySettings::operator = (const DisplaySettings& vs)
{
    if (this==&vs) return *this;
    setDisplaySettings(vs);
    return *this;
}

void DisplaySettings::setDisplaySettings(const DisplaySettings& vs)
{
    _displayType = vs._displayType;
    _stereo = vs._stereo;
    _stereoMode = vs._stereoMode;
    _eyeSeparation = vs._eyeSeparation;
    _screenWidth = vs._screenWidth;
    _screenHeight = vs._screenHeight;
    _screenDistance = vs._screenDistance;

    _splitStereoHorizontalEyeMapping = vs._splitStereoHorizontalEyeMapping;
    _splitStereoHorizontalSeparation = vs._splitStereoHorizontalSeparation;

    _splitStereoVerticalEyeMapping = vs._splitStereoVerticalEyeMapping;
    _splitStereoVerticalSeparation = vs._splitStereoVerticalSeparation;

    _splitStereoAutoAdjustAspectRatio = vs._splitStereoAutoAdjustAspectRatio;

    _doubleBuffer = vs._doubleBuffer;
    _RGB = vs._RGB;
    _depthBuffer = vs._depthBuffer;
    _minimumNumberAlphaBits = vs._minimumNumberAlphaBits;
    _minimumNumberStencilBits = vs._minimumNumberStencilBits;

    _maxNumOfGraphicsContexts = vs._maxNumOfGraphicsContexts;
}

void DisplaySettings::merge(const DisplaySettings& vs)
{
    if (_stereo       || vs._stereo)        _stereo = true;

    // need to think what to do about merging the stereo mode.

    if (_doubleBuffer || vs._doubleBuffer)  _doubleBuffer = true;
    if (_RGB          || vs._RGB)           _RGB = true;
    if (_depthBuffer  || vs._depthBuffer)   _depthBuffer = true;

    if (vs._minimumNumberAlphaBits>_minimumNumberAlphaBits) _minimumNumberAlphaBits = vs._minimumNumberAlphaBits;
    if (vs._minimumNumberStencilBits>_minimumNumberStencilBits) _minimumNumberStencilBits = vs._minimumNumberStencilBits;
}

void DisplaySettings::setDefaults()
{
    _displayType = MONITOR;

    _stereo = false;
    _stereoMode = ANAGLYPHIC;
    _eyeSeparation = 0.05f;
    _screenWidth = 0.325f;
    _screenHeight = 0.26f;
    _screenDistance = 0.5f;

    _splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT;
    _splitStereoHorizontalSeparation = 0;

    _splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT;
    _splitStereoVerticalSeparation = 0;

    _splitStereoAutoAdjustAspectRatio = true;

    _doubleBuffer = true;
    _RGB = true;
    _depthBuffer = true;
    _minimumNumberAlphaBits = 0;
    _minimumNumberStencilBits = 0;

    _maxNumOfGraphicsContexts = 3;
}

static ApplicationUsageProxy DisplaySetting_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_DISPLAY_TYPE <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY");
static ApplicationUsageProxy DisplaySetting_e1(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO_MODE <mode>","QUAD_BUFFER | ANAGLYPHIC | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE");
static ApplicationUsageProxy DisplaySetting_e2(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO <mode>","OFF | ON");
static ApplicationUsageProxy DisplaySetting_e3(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_EYE_SEPARATION <float>","physical distance between eyes");
static ApplicationUsageProxy DisplaySetting_e4(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_DISTANCE <float>","physical distance between eyes and screen");
static ApplicationUsageProxy DisplaySetting_e5(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_HEIGHT <float>","physical screen height");
static ApplicationUsageProxy DisplaySetting_e6(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_WIDTH <float>","physical screen width");
static ApplicationUsageProxy DisplaySetting_e7(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING <mode>","LEFT_EYE_LEFT_VIEWPORT | LEFT_EYE_RIGHT_VIEWPORT");
static ApplicationUsageProxy DisplaySetting_e8(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION <float>","number of pixels between viewports");
static ApplicationUsageProxy DisplaySetting_e9(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING <mode>","LEFT_EYE_TOP_VIEWPORT | LEFT_EYE_BOTTOM_VIEWPORT");
static ApplicationUsageProxy DisplaySetting_e10(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO <mode>","OFF | ON  Default to ON to compenstate for the compression of the aspect ratio when viewing in split screen stereo.  Note, if you are setting fovx and fovy explicityly OFF should be used.");
static ApplicationUsageProxy DisplaySetting_e11(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_SEPARATION <float>","number of pixels between viewports");
static ApplicationUsageProxy DisplaySetting_e12(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS <int>","maximum number of graphics contexts to be used with applications.");

void DisplaySettings::readEnvironmentalVariables()
{
    char *ptr;

    if ((ptr = getenv("OSG_DISPLAY_TYPE")) != 0)
    {
        if (strcmp(ptr,"MONITOR")==0)
        {
            _displayType = MONITOR;
        }
        else
        if (strcmp(ptr,"POWERWALL")==0)
        {
            _displayType = POWERWALL;
        }
        else
        if (strcmp(ptr,"REALITY_CENTER")==0)
        {
            _displayType = REALITY_CENTER;
        }
        else
        if (strcmp(ptr,"HEAD_MOUNTED_DISPLAY")==0)
        {
            _displayType = HEAD_MOUNTED_DISPLAY;
        }
    }

    if( (ptr = getenv("OSG_STEREO_MODE")) != 0)
    {
        if (strcmp(ptr,"QUAD_BUFFER")==0)
        {
            _stereoMode = QUAD_BUFFER;
        }
        else
        if (strcmp(ptr,"ANAGLYPHIC")==0)
        {
            _stereoMode = ANAGLYPHIC;
        }
        else
        if (strcmp(ptr,"HORIZONTAL_SPLIT")==0)
        {
            _stereoMode = HORIZONTAL_SPLIT;
        }
        else
        if (strcmp(ptr,"VERTICAL_SPLIT")==0)
        {
            _stereoMode = VERTICAL_SPLIT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE")==0)
        {
            _stereoMode = LEFT_EYE;
        }
        else
        if (strcmp(ptr,"RIGHT_EYE")==0)
        {
            _stereoMode = RIGHT_EYE;
        }
    }

    if( (ptr = getenv("OSG_STEREO")) != 0)
    {
        if (strcmp(ptr,"OFF")==0)
        {
            _stereo = false;
        }
        else
        if (strcmp(ptr,"ON")==0)
        {
            _stereo = true;
        }
    }

    if( (ptr = getenv("OSG_EYE_SEPARATION")) != 0)
    {
        _eyeSeparation = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_WIDTH")) != 0)
    {
        _screenWidth = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_HEIGHT")) != 0)
    {
        _screenHeight = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_DISTANCE")) != 0)
    {
        _screenDistance = atof(ptr);
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING")) != 0)
    {
        if (strcmp(ptr,"LEFT_EYE_LEFT_VIEWPORT")==0)
        {
            _splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE_RIGHT_VIEWPORT")==0)
        {
            _splitStereoHorizontalEyeMapping = LEFT_EYE_RIGHT_VIEWPORT;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION")) != 0)
    {
        _splitStereoHorizontalSeparation = atoi(ptr);
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING")) != 0)
    {
        if (strcmp(ptr,"LEFT_EYE_TOP_VIEWPORT")==0)
        {
            _splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE_BOTTOM_VIEWPORT")==0)
        {
            _splitStereoVerticalEyeMapping = LEFT_EYE_BOTTOM_VIEWPORT;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO")) != 0)
    {
        if (strcmp(ptr,"OFF")==0)
        {
            _splitStereoAutoAdjustAspectRatio = false;
        }
        else
        if (strcmp(ptr,"ON")==0)
        {
            _splitStereoAutoAdjustAspectRatio = true;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_VERTICAL_SEPARATION")) != 0)
    {
        _splitStereoVerticalSeparation = atoi(ptr);
    }

    if( (ptr = getenv("OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS")) != 0)
    {
        _maxNumOfGraphicsContexts = atoi(ptr);
    }
}

void DisplaySettings::readCommandLine(ArgumentParser& arguments)
{

    // report the usage options.
    if (arguments.getApplicationUsage())
    {
        arguments.getApplicationUsage()->addCommandLineOption("--display <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY");
        arguments.getApplicationUsage()->addCommandLineOption("--stereo","Use default stereo mode which is ANAGLYPHIC if not overriden by environmental variable");
        arguments.getApplicationUsage()->addCommandLineOption("--stereo <mode>","ANAGLYPHIC | QUAD_BUFFER | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE | ON | OFF ");
        arguments.getApplicationUsage()->addCommandLineOption("--rgba","Request a RGBA color buffer visual");
        arguments.getApplicationUsage()->addCommandLineOption("--stencil","Request a stencil buffer visual");
    }

    std::string str;
    while(arguments.read("--display",str))
    {
        if (str=="MONITOR") _displayType = MONITOR;
        else if (str=="POWERWALL") _displayType = POWERWALL;
        else if (str=="REALITY_CENTER") _displayType = REALITY_CENTER;
        else if (str=="HEAD_MOUNTED_DISPLAY") _displayType = HEAD_MOUNTED_DISPLAY;
    }

    int pos;
    while ((pos=arguments.find("--stereo"))!=0)
    {
        if (arguments.match(pos+1,"ANAGLYPHIC"))            { arguments.remove(pos,2); _stereo = true;_stereoMode = ANAGLYPHIC; }
        else if (arguments.match(pos+1,"QUAD_BUFFER"))      { arguments.remove(pos,2); _stereo = true;_stereoMode = QUAD_BUFFER; }
        else if (arguments.match(pos+1,"HORIZONTAL_SPLIT")) { arguments.remove(pos,2); _stereo = true;_stereoMode = HORIZONTAL_SPLIT; }
        else if (arguments.match(pos+1,"VERTICAL_SPLIT"))   { arguments.remove(pos,2); _stereo = true;_stereoMode = VERTICAL_SPLIT; }
        else if (arguments.match(pos+1,"LEFT_EYE"))         { arguments.remove(pos,2); _stereo = true;_stereoMode = LEFT_EYE; }
        else if (arguments.match(pos+1,"RIGHT_EYE"))        { arguments.remove(pos,2); _stereo = true;_stereoMode = RIGHT_EYE; }
        else if (arguments.match(pos+1,"ON"))               { arguments.remove(pos,2); _stereo = true; }
        else if (arguments.match(pos+1,"OFF"))              { arguments.remove(pos,2); _stereo = false; }
        else                                                { arguments.remove(pos); _stereo = true; }
    }

    while (arguments.read("--rgba"))
    {
        _RGB = true;
        _minimumNumberAlphaBits = 1;
    }

    while (arguments.read("--stencil"))
    {
        _minimumNumberStencilBits = 1;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 - Mozy, Inc.

#include <boost/bind.hpp>

#include "sleep.h"

#include "assert.h"
#include "fiber.h"
#include "scheduler.h"
#include "timer.h"

namespace Mordor {

static void scheduleMe(Scheduler *scheduler, Fiber::ptr fiber)
{
    scheduler->schedule(fiber);
}

void
sleep(TimerManager &timerManager, unsigned long long us)
{
    MORDOR_ASSERT(Scheduler::getThis());
    timerManager.registerTimer(us,
        boost::bind(&scheduleMe, Scheduler::getThis(), Fiber::getThis()));
    Scheduler::yieldTo();
}

void
sleep(unsigned long long us)
{
#ifdef WINDOWS
    Sleep((DWORD)(us / 1000));
#else
    struct timespec ts;
    ts.tv_sec = us / 1000000;
    ts.tv_nsec = (us % 1000) * 1000;
    while (true) {
        if (nanosleep(&ts, &ts) == -1) {
            if (errno == EINTR)
                continue;
            MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("nanosleep");
        }
        break;
    }
#endif
}

}
<commit_msg>fix for sleep on posix<commit_after>// Copyright (c) 2009 - Mozy, Inc.

#include <boost/bind.hpp>

#include "sleep.h"

#include "assert.h"
#include "fiber.h"
#include "scheduler.h"
#include "timer.h"

namespace Mordor {

static void scheduleMe(Scheduler *scheduler, Fiber::ptr fiber)
{
    scheduler->schedule(fiber);
}

void
sleep(TimerManager &timerManager, unsigned long long us)
{
    MORDOR_ASSERT(Scheduler::getThis());
    timerManager.registerTimer(us,
        boost::bind(&scheduleMe, Scheduler::getThis(), Fiber::getThis()));
    Scheduler::yieldTo();
}

void
sleep(unsigned long long us)
{
#ifdef WINDOWS
    Sleep((DWORD)(us / 1000));
#else
    struct timespec ts;
    ts.tv_sec = us / 1000000;
    ts.tv_nsec = (us % 1000000) * 1000;
    while (true) {
        if (nanosleep(&ts, &ts) == -1) {
            if (errno == EINTR)
                continue;
            MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("nanosleep");
        }
        break;
    }
#endif
}

}
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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.

#ifndef URI_HPP
#define URI_HPP

#include <gsl.h>
#include <unordered_map>

namespace uri {

  /**
   * Representation of RFC 3986 URI's.
   * Ref. https://tools.ietf.org/html/rfc3986
   **/
  class URI {
  public:
    /*
     * Default constructor
     */
    URI() = default;

    /*
     * Default copy and move constructors
     */
    URI(URI&) = default;
    URI(URI&&) = default;

    /*
     * Default destructor
     */
    ~URI() = default;

    /*
     * Default assignment operators
     */
    URI& operator=(const URI&) = default;
    URI& operator=(URI&&) = default;

    //
    // We might do a span-based constructor later.
    // URI(gsl::span<const char>);
    //

    /**
     * @brief Construct using a C-String
     *
     * @param uri : A C-String representing a uri
     */
    URI(const char* uri);

    /**
     * @brief Construct using a string
     *
     * @param uri : A string representing a uri
     */
    URI(const std::string& uri);

    ///////////////////////////////////////////////
    //----------RFC-specified URI parts----------//
    ///////////////////////////////////////////////

    /**
     * @brief Get scheme.
     *
     * E.g. 'http', 'file', 'ftp' etc.
     *
     * @return The scheme
     */
    const std::string& scheme() const;

    /**
     * @brief Get userinfo.
     *
     * E.g. 'username@'...
     *
     * @return The user's information
     */
    const std::string& userinfo() const;

    /**
     * @brief Get host.
     *
     * E.g. 'includeos.org', '10.0.0.42' etc.
     *
     * @return The host's information
     */
    const std::string& host() const;

    /**
     * @brief Get the raw port number in decimal character representation.
     *
     * @return The raw port number as a string
     */
    const std::string& port_str() const;

    /**
     * @brief Get numeric port number.
     *
     * @warning The RFC doesn't specify dimension. This funcion will truncate
     * any overflowing digits.
     *
     * @return The numeric port number as a 16-bit number
     */
    uint16_t port() const noexcept;

    /**
     * @brief Get the path.
     *
     * E.g. /pictures/logo.png
     *
     * @return The path information
     */
    const std::string& path() const;

    /**
     * @brief Get the complete unparsed query string.
     *
     * @return The complete unparsed query string
     */
    const std::string& query() const;

    /**
     * @brief Get the fragment part.
     *
     * E.g. "...#anchor1"
     *
     * @return the fragment part
     */
    const std::string& fragment() const;

    /**
     * @brief Get the URI-decoded value of a query-string key.
     *
     * @param key : The key to find the associated value
     *
     * @return The key's associated value
     *
     * @example For the query: "?name=Bjarne%20Stroustrup",
     * query("name") returns "Bjarne Stroustrup"
     */
    const std::string& query(const std::string& key);

    /**
     * @brief Get a string representation of this
     * class
     *
     * @return - A string representation
     */
    std::string to_string() const;

    /**
     * @brief Operator to transform this class
     * into string form
     */
    operator std::string () const;

  private:
    /*
     * A copy of the data representing a uri
     */
    std::string uri_str_;

    mutable uint16_t port_;

    Span_t scheme_;
    Span_t userinfo_;
    Span_t host_;
    Span_t port_str_;
    Span_t path_;
    Span_t query_;
    Span_t fragment_;

    static const Span_t zero_span_;

    std::unordered_map<std::string,std::string> queries_;

    /**
     * @brief Parse the given string representing a uri
     * into its given parts according to RFC 3986
     *
     * @param uri : The string representing a uri
     */
    void parse(const std::string& uri);

    /**
     * @brief Load queries into the map
     */
    void load_queries();

  }; // class uri::URI

  /**
   * @brief Operator to stream the contents of a {URI}
   * to the specified output stream device
   *
   * @param output_device : The output stream device
   * @param uri : The {URI} to send to the output stream
   *
   * @return A reference to the specified output stream device
   */
  std::ostream& operator<< (std::ostream& output_device, const URI& uri);

} // namespace uri

#endif //< URI_HPP
<commit_msg>Updated API Doc for URI(const std::string&)<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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.

#ifndef URI_HPP
#define URI_HPP

#include <gsl.h>
#include <unordered_map>

namespace uri {

  /**
   * Representation of RFC 3986 URI's.
   * Ref. https://tools.ietf.org/html/rfc3986
   **/
  class URI {
  public:
    /*
     * Default constructor
     */
    URI() = default;

    /*
     * Default copy and move constructors
     */
    URI(URI&) = default;
    URI(URI&&) = default;

    /*
     * Default destructor
     */
    ~URI() = default;

    /*
     * Default assignment operators
     */
    URI& operator=(const URI&) = default;
    URI& operator=(URI&&) = default;

    //
    // We might do a span-based constructor later.
    // URI(gsl::span<const char>);
    //

    /**
     * @brief Construct using a C-String
     *
     * @param uri : A C-String representing a uri
     */
    URI(const char* uri);

    /**
     * @brief Construct using a {std::string}
     *
     * @param uri : A {std::string} representing a uri
     */
    URI(const std::string& uri);

    ///////////////////////////////////////////////
    //----------RFC-specified URI parts----------//
    ///////////////////////////////////////////////

    /**
     * @brief Get scheme.
     *
     * E.g. 'http', 'file', 'ftp' etc.
     *
     * @return The scheme
     */
    const std::string& scheme() const;

    /**
     * @brief Get userinfo.
     *
     * E.g. 'username@'...
     *
     * @return The user's information
     */
    const std::string& userinfo() const;

    /**
     * @brief Get host.
     *
     * E.g. 'includeos.org', '10.0.0.42' etc.
     *
     * @return The host's information
     */
    const std::string& host() const;

    /**
     * @brief Get the raw port number in decimal character representation.
     *
     * @return The raw port number as a string
     */
    const std::string& port_str() const;

    /**
     * @brief Get numeric port number.
     *
     * @warning The RFC doesn't specify dimension. This funcion will truncate
     * any overflowing digits.
     *
     * @return The numeric port number as a 16-bit number
     */
    uint16_t port() const noexcept;

    /**
     * @brief Get the path.
     *
     * E.g. /pictures/logo.png
     *
     * @return The path information
     */
    const std::string& path() const;

    /**
     * @brief Get the complete unparsed query string.
     *
     * @return The complete unparsed query string
     */
    const std::string& query() const;

    /**
     * @brief Get the fragment part.
     *
     * E.g. "...#anchor1"
     *
     * @return the fragment part
     */
    const std::string& fragment() const;

    /**
     * @brief Get the URI-decoded value of a query-string key.
     *
     * @param key : The key to find the associated value
     *
     * @return The key's associated value
     *
     * @example For the query: "?name=Bjarne%20Stroustrup",
     * query("name") returns "Bjarne Stroustrup"
     */
    const std::string& query(const std::string& key);

    /**
     * @brief Get a string representation of this
     * class
     *
     * @return - A string representation
     */
    std::string to_string() const;

    /**
     * @brief Operator to transform this class
     * into string form
     */
    operator std::string () const;

  private:
    /*
     * A copy of the data representing a uri
     */
    std::string uri_str_;

    mutable uint16_t port_;

    Span_t scheme_;
    Span_t userinfo_;
    Span_t host_;
    Span_t port_str_;
    Span_t path_;
    Span_t query_;
    Span_t fragment_;

    static const Span_t zero_span_;

    std::unordered_map<std::string,std::string> queries_;

    /**
     * @brief Parse the given string representing a uri
     * into its given parts according to RFC 3986
     *
     * @param uri : The string representing a uri
     */
    void parse(const std::string& uri);

    /**
     * @brief Load queries into the map
     */
    void load_queries();

  }; // class uri::URI

  /**
   * @brief Operator to stream the contents of a {URI}
   * to the specified output stream device
   *
   * @param output_device : The output stream device
   * @param uri : The {URI} to send to the output stream
   *
   * @return A reference to the specified output stream device
   */
  std::ostream& operator<< (std::ostream& output_device, const URI& uri);

} // namespace uri

#endif //< URI_HPP
<|endoftext|>


<commit_before>/**********************************************************\

  Auto-generated perc.cpp

  This file contains the auto-generated main plugin object
  implementation for the perc project

\**********************************************************/

#include "percAPI.h"

#include "perc.h"
#include <windows.h>

///////////////////////////////////////////////////////////////////////////////
/// @fn perc::StaticInitialize()
///
/// @brief  Called from PluginFactory::globalPluginInitialize()
///
/// @see FB::FactoryBase::globalPluginInitialize
///////////////////////////////////////////////////////////////////////////////
void perc::StaticInitialize()
{
    // Place one-time initialization stuff here; As of FireBreath 1.4 this should only
    // be called once per process

	MessageBox(NULL, L"StaticInitialize", L"", 0);
}

///////////////////////////////////////////////////////////////////////////////
/// @fn perc::StaticInitialize()
///
/// @brief  Called from PluginFactory::globalPluginDeinitialize()
///
/// @see FB::FactoryBase::globalPluginDeinitialize
///////////////////////////////////////////////////////////////////////////////
void perc::StaticDeinitialize()
{
    // Place one-time deinitialization stuff here. As of FireBreath 1.4 this should
    // always be called just before the plugin library is unloaded
}

///////////////////////////////////////////////////////////////////////////////
/// @brief  perc constructor.  Note that your API is not available
///         at this point, nor the window.  For best results wait to use
///         the JSAPI object until the onPluginReady method is called
///////////////////////////////////////////////////////////////////////////////
perc::perc()
{
}

///////////////////////////////////////////////////////////////////////////////
/// @brief  perc destructor.
///////////////////////////////////////////////////////////////////////////////
perc::~perc()
{
    // This is optional, but if you reset m_api (the shared_ptr to your JSAPI
    // root object) and tell the host to free the retained JSAPI objects then
    // unless you are holding another shared_ptr reference to your JSAPI object
    // they will be released here.
    releaseRootJSAPI();
    m_host->freeRetainedObjects();
}

void perc::onPluginReady()
{
    // When this is called, the BrowserHost is attached, the JSAPI object is
    // created, and we are ready to interact with the page and such.  The
    // PluginWindow may or may not have already fire the AttachedEvent at
    // this point.
}

void perc::shutdown()
{
    // This will be called when it is time for the plugin to shut down;
    // any threads or anything else that may hold a shared_ptr to this
    // object should be released here so that this object can be safely
    // destroyed. This is the last point that shared_from_this and weak_ptr
    // references to this object will be valid
}

///////////////////////////////////////////////////////////////////////////////
/// @brief  Creates an instance of the JSAPI object that provides your main
///         Javascript interface.
///
/// Note that m_host is your BrowserHost and shared_ptr returns a
/// FB::PluginCorePtr, which can be used to provide a
/// boost::weak_ptr<perc> for your JSAPI class.
///
/// Be very careful where you hold a shared_ptr to your plugin class from,
/// as it could prevent your plugin class from getting destroyed properly.
///////////////////////////////////////////////////////////////////////////////
FB::JSAPIPtr perc::createJSAPI()
{
    // m_host is the BrowserHost
    return boost::make_shared<percAPI>(FB::ptr_cast<perc>(shared_from_this()), m_host);
}

bool perc::onMouseDown(FB::MouseDownEvent *evt, FB::PluginWindow *)
{
    //printf("Mouse down at: %d, %d\n", evt->m_x, evt->m_y);
    return false;
}

bool perc::onMouseUp(FB::MouseUpEvent *evt, FB::PluginWindow *)
{
    //printf("Mouse up at: %d, %d\n", evt->m_x, evt->m_y);
    return false;
}

bool perc::onMouseMove(FB::MouseMoveEvent *evt, FB::PluginWindow *)
{
    //printf("Mouse move at: %d, %d\n", evt->m_x, evt->m_y);
    return false;
}
bool perc::onWindowAttached(FB::AttachedEvent *evt, FB::PluginWindow *)
{
    // The window is attached; act appropriately
    return false;
}

bool perc::onWindowDetached(FB::DetachedEvent *evt, FB::PluginWindow *)
{
    // The window is about to be detached; act appropriately
    return false;
}

<commit_msg>Stop putting up a message box when loading the plugin.<commit_after>/**********************************************************\

  Auto-generated perc.cpp

  This file contains the auto-generated main plugin object
  implementation for the perc project

\**********************************************************/

#include "percAPI.h"

#include "perc.h"
#include <windows.h>

///////////////////////////////////////////////////////////////////////////////
/// @fn perc::StaticInitialize()
///
/// @brief  Called from PluginFactory::globalPluginInitialize()
///
/// @see FB::FactoryBase::globalPluginInitialize
///////////////////////////////////////////////////////////////////////////////
void perc::StaticInitialize()
{
    // Place one-time initialization stuff here; As of FireBreath 1.4 this should only
    // be called once per process
}

///////////////////////////////////////////////////////////////////////////////
/// @fn perc::StaticInitialize()
///
/// @brief  Called from PluginFactory::globalPluginDeinitialize()
///
/// @see FB::FactoryBase::globalPluginDeinitialize
///////////////////////////////////////////////////////////////////////////////
void perc::StaticDeinitialize()
{
    // Place one-time deinitialization stuff here. As of FireBreath 1.4 this should
    // always be called just before the plugin library is unloaded
}

///////////////////////////////////////////////////////////////////////////////
/// @brief  perc constructor.  Note that your API is not available
///         at this point, nor the window.  For best results wait to use
///         the JSAPI object until the onPluginReady method is called
///////////////////////////////////////////////////////////////////////////////
perc::perc()
{
}

///////////////////////////////////////////////////////////////////////////////
/// @brief  perc destructor.
///////////////////////////////////////////////////////////////////////////////
perc::~perc()
{
    // This is optional, but if you reset m_api (the shared_ptr to your JSAPI
    // root object) and tell the host to free the retained JSAPI objects then
    // unless you are holding another shared_ptr reference to your JSAPI object
    // they will be released here.
    releaseRootJSAPI();
    m_host->freeRetainedObjects();
}

void perc::onPluginReady()
{
    // When this is called, the BrowserHost is attached, the JSAPI object is
    // created, and we are ready to interact with the page and such.  The
    // PluginWindow may or may not have already fire the AttachedEvent at
    // this point.
}

void perc::shutdown()
{
    // This will be called when it is time for the plugin to shut down;
    // any threads or anything else that may hold a shared_ptr to this
    // object should be released here so that this object can be safely
    // destroyed. This is the last point that shared_from_this and weak_ptr
    // references to this object will be valid
}

///////////////////////////////////////////////////////////////////////////////
/// @brief  Creates an instance of the JSAPI object that provides your main
///         Javascript interface.
///
/// Note that m_host is your BrowserHost and shared_ptr returns a
/// FB::PluginCorePtr, which can be used to provide a
/// boost::weak_ptr<perc> for your JSAPI class.
///
/// Be very careful where you hold a shared_ptr to your plugin class from,
/// as it could prevent your plugin class from getting destroyed properly.
///////////////////////////////////////////////////////////////////////////////
FB::JSAPIPtr perc::createJSAPI()
{
    // m_host is the BrowserHost
    return boost::make_shared<percAPI>(FB::ptr_cast<perc>(shared_from_this()), m_host);
}

bool perc::onMouseDown(FB::MouseDownEvent *evt, FB::PluginWindow *)
{
    //printf("Mouse down at: %d, %d\n", evt->m_x, evt->m_y);
    return false;
}

bool perc::onMouseUp(FB::MouseUpEvent *evt, FB::PluginWindow *)
{
    //printf("Mouse up at: %d, %d\n", evt->m_x, evt->m_y);
    return false;
}

bool perc::onMouseMove(FB::MouseMoveEvent *evt, FB::PluginWindow *)
{
    //printf("Mouse move at: %d, %d\n", evt->m_x, evt->m_y);
    return false;
}
bool perc::onWindowAttached(FB::AttachedEvent *evt, FB::PluginWindow *)
{
    // The window is attached; act appropriately
    return false;
}

bool perc::onWindowDetached(FB::DetachedEvent *evt, FB::PluginWindow *)
{
    // The window is about to be detached; act appropriately
    return false;
}

<|endoftext|>


<commit_before>//sg: this is going to be the primary vision node for qubo (or future robots, whatever)
#include "vision_node.h"

using namespace std;
using namespace ros;
using namespace AVT::VmbAPI;

int VisionNode::vmb_err(const int func_call, const string err_msg) {
	if (func_call != VmbErrorSuccess){
		ROS_ERROR("%s, code: %i", err_msg.c_str(), func_call);
		return func_call;
	}
	return func_call;
}

//you need to pass in a node handle, and a camera feed, which should be a file path either to a physical device or to a video
VisionNode::VisionNode(NodeHandle n, NodeHandle np, string feed)
	:	m_buoy_server(n, "buoy_action", boost::bind(&VisionNode::findBuoy, this, _1, &m_buoy_server), false),
		m_gate_server(n, "gate_action", boost::bind(&VisionNode::findGate, this, _1, &m_gate_server), false),
		m_blob_server(n, "blob_action", boost::bind(&VisionNode::findBlob, this, _1, &m_blob_server), false)

{

	// isdigit makes sure checks if we're dealing with a number (like if want to open the default camera by passing a 0). If we are we convert our string to an int (VideoCapture won't correctly open the camera with the string in this case);
	//this could give us problems if we pass something like "0followed_by_string" but just don't do that.

	//sgillen@20170429-07:04 we really don't even need this... we can just pass in /dev/video0 if we want the web camera... I'll leave it for now though
	if(isdigit(feed.c_str()[0])){
		m_cap = cv::VideoCapture(atoi(feed.c_str()));
	}
	else{
		m_cap = cv::VideoCapture(feed);
	}

		//make sure we have something valid
    if(!m_cap.isOpened()){
        ROS_ERROR("couldn't open file/camera  %s\n now exiting" ,feed.c_str());
        exit(0);
    }

	//TODO give option to user to specify the name of the video
	//TODO make sure this doesn't fail when specifying a directory that does not yet exist

	string output_dir;
	np.param<string>("output_dir", output_dir, ""); //this line will populate the output_dir variable if it's specified in the launch file

	//TODO change variable names
	if(!output_dir.empty()){

		stringstream output_ss;
		auto t = time(nullptr);
		auto tm = *localtime(&t);

		output_ss << output_dir;
		output_ss << put_time(&tm, "%Y%m%d_%H-%M-%S");
		output_ss << ".avi";

		string output_str = output_ss.str();

		int ex = static_cast<int>(m_cap.get(CV_CAP_PROP_FOURCC));

		cv::Size S = cv::Size((int) m_cap.get(CV_CAP_PROP_FRAME_WIDTH),    // Acquire input size
					  (int) m_cap.get(CV_CAP_PROP_FRAME_HEIGHT));

		//sgillen@20172107-06:21 I found more problems trying to keep the extension (by passing ex as the second argument) than I did by forcing the output to be CV_FOURCC('M','J','P','G')
		//m_output_video.open(output_str, ex, m_cap.get(CV_CAP_PROP_FPS), S, true);
		m_output_video.open(output_str, CV_FOURCC('M','J','P','G'), m_cap.get(CV_CAP_PROP_FPS), S, true);

		if(!m_output_video.isOpened()){
			ROS_ERROR("problem opening output video! we tried saving it as %s, now exiting" ,output_str.c_str());
			exit(0);
		}

		ROS_INFO("output video being saved as %s" , output_str.c_str());
	}

	//register all services here
	//------------------------------------------------------------------------------
	m_test_srv = n.advertiseService("service_test", &VisionNode::serviceTest, this);

	//start your action servers here
	//------------------------------------------------------------------------------
	m_buoy_server.start();
	m_gate_server.start();
	ROS_INFO("servers started");
}

VisionNode::~VisionNode(){
    //sg: may need to close the cameras here not sure..
}

void VisionNode::update(){

	m_cap >> m_img;
	//if one of our frames was empty it means we ran out of footage, should only happen with test feeds or if a camera breaks I guess
	if(m_img.empty()){
		ROS_ERROR("ran out of video (one of the frames was empty) exiting node now");
		exit(0);
	}

	//if the user didn't specify a directory this will not be open
	if(m_output_video.isOpened()){
		ROS_ERROR("writing image!");
		m_output_video << m_img;
	}

	spinOnce();
}

/*
* Past this point is a collection of services and
* actions that will be able to called from any other node
* =================================================================================================================
*/
bool VisionNode::serviceTest(ram_msgs::bool_bool::Request &req, ram_msgs::bool_bool::Response &res){
    ROS_ERROR("service called successfully");
}

//There are the definitions for all of our actionlib actions, may be moved to it's own class not sure yet.
//=================================================================================================================
void VisionNode::testExecute(const ram_msgs::VisionNavGoalConstPtr& goal, actionlib::SimpleActionServer<ram_msgs::VisionNavAction> *as){
    //    goal->test_feedback = 5;
    ROS_ERROR("You called the action well done!");
    as->setSucceeded();
}

//if a buoy is found on frame finds where it is and returns the center offset
void VisionNode::findBuoy(const ram_msgs::VisionNavGoalConstPtr& goal,  actionlib::SimpleActionServer<ram_msgs::VisionNavAction> *as){

	BuoyAction action = BuoyAction(as);

	while(true){
		action.updateAction(m_img); //this will also publish the feedback
	}

	as->setSucceeded();
}

void VisionNode::findGate(const ram_msgs::VisionNavGoalConstPtr& goal,  actionlib::SimpleActionServer<ram_msgs::VisionNavAction> *as){

	GateAction action = GateAction();

	while(true){
		ROS_ERROR("updating action");
		action.updateAction(m_img);
	}

	as->setSucceeded();
}

void VisionNode::findBlob(const ram_msgs::VisionNavGoalConstPtr& goal,  actionlib::SimpleActionServer<ram_msgs::VisionNavAction> *as){

	BlobAction action = BlobAction(as);

	while(true){
		ROS_ERROR("updating action");
		action.updateAction(m_img);
	}

	as->setSucceeded();
}
<commit_msg>starts the server now<commit_after>//sg: this is going to be the primary vision node for qubo (or future robots, whatever)
#include "vision_node.h"

using namespace std;
using namespace ros;
using namespace AVT::VmbAPI;

int VisionNode::vmb_err(const int func_call, const string err_msg) {
	if (func_call != VmbErrorSuccess){
		ROS_ERROR("%s, code: %i", err_msg.c_str(), func_call);
		return func_call;
	}
	return func_call;
}

//you need to pass in a node handle, and a camera feed, which should be a file path either to a physical device or to a video
VisionNode::VisionNode(NodeHandle n, NodeHandle np, string feed)
	:	m_buoy_server(n, "buoy_action", boost::bind(&VisionNode::findBuoy, this, _1, &m_buoy_server), false),
		m_gate_server(n, "gate_action", boost::bind(&VisionNode::findGate, this, _1, &m_gate_server), false),
		m_blob_server(n, "blob_action", boost::bind(&VisionNode::findBlob, this, _1, &m_blob_server), false)

{

	// isdigit makes sure checks if we're dealing with a number (like if want to open the default camera by passing a 0). If we are we convert our string to an int (VideoCapture won't correctly open the camera with the string in this case);
	//this could give us problems if we pass something like "0followed_by_string" but just don't do that.

	//sgillen@20170429-07:04 we really don't even need this... we can just pass in /dev/video0 if we want the web camera... I'll leave it for now though
	if(isdigit(feed.c_str()[0])){
		m_cap = cv::VideoCapture(atoi(feed.c_str()));
	}
	else{
		m_cap = cv::VideoCapture(feed);
	}

		//make sure we have something valid
    if(!m_cap.isOpened()){
        ROS_ERROR("couldn't open file/camera  %s\n now exiting" ,feed.c_str());
        exit(0);
    }

	//TODO give option to user to specify the name of the video
	//TODO make sure this doesn't fail when specifying a directory that does not yet exist

	string output_dir;
	np.param<string>("output_dir", output_dir, ""); //this line will populate the output_dir variable if it's specified in the launch file

	//TODO change variable names
	if(!output_dir.empty()){

		stringstream output_ss;
		auto t = time(nullptr);
		auto tm = *localtime(&t);

		output_ss << output_dir;
		output_ss << put_time(&tm, "%Y%m%d_%H-%M-%S");
		output_ss << ".avi";

		string output_str = output_ss.str();

		int ex = static_cast<int>(m_cap.get(CV_CAP_PROP_FOURCC));

		cv::Size S = cv::Size((int) m_cap.get(CV_CAP_PROP_FRAME_WIDTH),    // Acquire input size
					  (int) m_cap.get(CV_CAP_PROP_FRAME_HEIGHT));

		//sgillen@20172107-06:21 I found more problems trying to keep the extension (by passing ex as the second argument) than I did by forcing the output to be CV_FOURCC('M','J','P','G')
		//m_output_video.open(output_str, ex, m_cap.get(CV_CAP_PROP_FPS), S, true);
		m_output_video.open(output_str, CV_FOURCC('M','J','P','G'), m_cap.get(CV_CAP_PROP_FPS), S, true);

		if(!m_output_video.isOpened()){
			ROS_ERROR("problem opening output video! we tried saving it as %s, now exiting" ,output_str.c_str());
			exit(0);
		}

		ROS_INFO("output video being saved as %s" , output_str.c_str());
	}

	//register all services here
	//------------------------------------------------------------------------------
	m_test_srv = n.advertiseService("service_test", &VisionNode::serviceTest, this);

	//start your action servers here
	//------------------------------------------------------------------------------
	m_buoy_server.start();
	m_gate_server.start();
	m_blob_server.start();
	ROS_INFO("servers started");
}

VisionNode::~VisionNode(){
    //sg: may need to close the cameras here not sure..
}

void VisionNode::update(){

	m_cap >> m_img;
	//if one of our frames was empty it means we ran out of footage, should only happen with test feeds or if a camera breaks I guess
	if(m_img.empty()){
		ROS_ERROR("ran out of video (one of the frames was empty) exiting node now");
		exit(0);
	}

	//if the user didn't specify a directory this will not be open
	if(m_output_video.isOpened()){
		ROS_ERROR("writing image!");
		m_output_video << m_img;
	}

	spinOnce();
}

/*
* Past this point is a collection of services and
* actions that will be able to called from any other node
* =================================================================================================================
*/
bool VisionNode::serviceTest(ram_msgs::bool_bool::Request &req, ram_msgs::bool_bool::Response &res){
    ROS_ERROR("service called successfully");
}

//There are the definitions for all of our actionlib actions, may be moved to it's own class not sure yet.
//=================================================================================================================
void VisionNode::testExecute(const ram_msgs::VisionNavGoalConstPtr& goal, actionlib::SimpleActionServer<ram_msgs::VisionNavAction> *as){
    //    goal->test_feedback = 5;
    ROS_ERROR("You called the action well done!");
    as->setSucceeded();
}

//if a buoy is found on frame finds where it is and returns the center offset
void VisionNode::findBuoy(const ram_msgs::VisionNavGoalConstPtr& goal,  actionlib::SimpleActionServer<ram_msgs::VisionNavAction> *as){

	BuoyAction action = BuoyAction(as);

	while(true){
		action.updateAction(m_img); //this will also publish the feedback
	}

	as->setSucceeded();
}

void VisionNode::findGate(const ram_msgs::VisionNavGoalConstPtr& goal,  actionlib::SimpleActionServer<ram_msgs::VisionNavAction> *as){

	GateAction action = GateAction();

	while(true){
		ROS_ERROR("updating action");
		action.updateAction(m_img);
	}

	as->setSucceeded();
}

void VisionNode::findBlob(const ram_msgs::VisionNavGoalConstPtr& goal,  actionlib::SimpleActionServer<ram_msgs::VisionNavAction> *as){

	BlobAction action = BlobAction(as);

	while(true){
		ROS_ERROR("updating action");
		action.updateAction(m_img);
	}

	as->setSucceeded();
}
<|endoftext|>