<commit_before>#ifndef FUNCTIONS_HPP
#define FUNCTIONS_HPP

#include "constants.hpp"

namespace cutehmi {

/**
 * Epsilon for a number. Get epsilon for real number @a r, that means smallest number which added to @a r changes value of @a r.
 * @param r real number.
 * @return smallest number, which added to @a r changes value of @a r. If @a r is positive number, then returned number is also
 * positive. Otherwise negative number is returned.
 *
 * @see absEps().
 */
inline
qreal eps(qreal r)
{
	static constexpr qreal MACHINE_EPS = std::numeric_limits<qreal>::epsilon() * 0.5;

	int exp;
	std::frexp(r, & exp);
	return std::ldexp(std::signbit(r) ? -MACHINE_EPS : MACHINE_EPS, exp);
}

/**
 * Absolute epsilon for a number. Works in similar way to eps() function, except that absolute value is returned instead of signed
 * one.
 * @param r real number.
 * @return smallest number which added to @a r changes value of @a r. Always non-negative value is returned.
 *
 * @see eps().
 */
inline
qreal absEps(qreal r)
{
	static constexpr qreal MACHINE_EPS = std::numeric_limits<qreal>::epsilon() * 0.5;

	int exp;
	std::frexp(r, & exp);
	return std::ldexp(MACHINE_EPS, exp);
}

/**
 * Approximately equal. Compares real numbers @a r1, @a r2.
 * @param r1 first number to compare.
 * @param r2 second number to compare.
 * @param eps epsilon tolerance parameter used in comparison.
 * @return @p true when @a r1 and @a r2 are approximately equal, @p false otherwise.
 *
 * @see ale().
 *
 * @internal Donald E. Knuth "Art of Computer Programming" [P 4.2.2 Vol2].
 */
inline
bool ape(qreal r1, qreal r2, qreal eps = EPS)
{
	int exp1, exp2;
	std::frexp(r1, & exp1);
	std::frexp(r2, & exp2);

	// For some reason <= is used in the book to compare both sides. There may be a reason for this, so I'll leave it for now, but
	// the consequence is that image of a function is a bit weird, e.g.:
	// ape(1.0, 1.99, 0.25) -> false, ape(1.0, 2.0, 0.25) -> true, ape(1.0, 2.01, 0.25) -> false
	return std::abs(r2 - r1) <= std::ldexp(eps, std::max(exp1, exp2));
}

/**
 * Almost equal. Compares real numbers @a r1, @a r2. Function similar to ape(), however ale() is slightly stronger than ape() (@a r1
 * and @a r2 must be slightly closer to each other to manifest equality). This function can be problematic, when one of the values
 * is exactly zero, because in such case it returns @p true only if second argument is also exactly zero.
 * @param r1 first number to compare.
 * @param r2 second number to compare.
 * @param eps epsilon tolerance parameter used in comparison.
 * @return @p true when @a r1 and @a r2 are almost equal, @p false otherwise.
 *
 * @see ape().
 *
 * @internal Donald E. Knuth "Art of Computer Programming" [P 4.2.2 Vol2].
 */
inline
bool ale(qreal r1, qreal r2, qreal eps = EPS)
{
	int exp1, exp2;
	std::frexp(r1, & exp1);
	std::frexp(r2, & exp2);

	return std::abs(r2 - r1) <= std::ldexp(eps, std::min(exp1, exp2));
}

/**
 * Considerably less than.
 * @param r1 first number to compare.
 * @param r2 second number to compare.
 * @param eps epsilon tolerance parameter used in comparison.
 * @return @p true when @a r1 is considerably less than @a r2, @p false otherwise.
 *
 * @internal Donald E. Knuth "Art of Computer Programming" [P 4.2.2 Vol2].
 */
inline
bool clt(qreal r1, qreal r2, qreal eps = EPS)
{
	int exp1, exp2;
	std::frexp(r1, & exp1);
	std::frexp(r2, & exp2);

	return r2 - r1 > std::ldexp(eps, std::max(exp1, exp2));
}

/**
 * Considerably greater than.
 * @param r1 first number to compare.
 * @param r2 second number to compare.
 * @param eps epsilon tolerance parameter used in comparison.
 * @return @p true when @a r1 is considerably greater than @a r2, @p false otherwise.
 *
 * @internal Donald E. Knuth "Art of Computer Programming" [P 4.2.2 Vol2].
 */
inline
bool cgt(qreal r1, qreal r2, qreal eps = EPS)
{
	int exp1, exp2;
	std::frexp(r1, & exp1);
	std::frexp(r2, & exp2);

	return r1 - r2 > std::ldexp(eps, std::max(exp1, exp2));
}

}

#endif // FUNCTIONS_HPP
<commit_msg>Rename constants.<commit_after>#ifndef FUNCTIONS_HPP
#define FUNCTIONS_HPP

#include "constants.hpp"

namespace cutehmi {

/**
 * Epsilon for a number. Get epsilon for real number @a r, that means smallest number which added to @a r changes value of @a r.
 * @param r real number.
 * @return smallest number, which added to @a r changes value of @a r. If @a r is positive number, then returned number is also
 * positive. Otherwise negative number is returned.
 *
 * @see absEps().
 */
inline
qreal eps(qreal r)
{
	static constexpr qreal HALF_EPS = std::numeric_limits<qreal>::epsilon() * 0.5;

	int exp;
	std::frexp(r, & exp);
	return std::ldexp(std::signbit(r) ? -HALF_EPS : HALF_EPS, exp);
}

/**
 * Absolute epsilon for a number. Works in similar way to eps() function, except that absolute value is returned instead of signed
 * one.
 * @param r real number.
 * @return smallest number which added to @a r changes value of @a r. Always non-negative value is returned.
 *
 * @see eps().
 */
inline
qreal absEps(qreal r)
{
	static constexpr qreal HALF_EPS = std::numeric_limits<qreal>::epsilon() * 0.5;

	int exp;
	std::frexp(r, & exp);
	return std::ldexp(HALF_EPS, exp);
}

/**
 * Approximately equal. Compares real numbers @a r1, @a r2.
 * @param r1 first number to compare.
 * @param r2 second number to compare.
 * @param eps epsilon tolerance parameter used in comparison.
 * @return @p true when @a r1 and @a r2 are approximately equal, @p false otherwise.
 *
 * @see ale().
 *
 * @internal Donald E. Knuth "Art of Computer Programming" [P 4.2.2 Vol2].
 */
inline
bool ape(qreal r1, qreal r2, qreal eps = EPS)
{
	int exp1, exp2;
	std::frexp(r1, & exp1);
	std::frexp(r2, & exp2);

	// For some reason <= is used in the book to compare both sides. There may be a reason for this, so I'll leave it for now, but
	// the consequence is that image of a function is a bit weird, e.g.:
	// ape(1.0, 1.99, 0.25) -> false, ape(1.0, 2.0, 0.25) -> true, ape(1.0, 2.01, 0.25) -> false
	return std::abs(r2 - r1) <= std::ldexp(eps, std::max(exp1, exp2));
}

/**
 * Almost equal. Compares real numbers @a r1, @a r2. Function similar to ape(), however ale() is slightly stronger than ape() (@a r1
 * and @a r2 must be slightly closer to each other to manifest equality). This function can be problematic, when one of the values
 * is exactly zero, because in such case it returns @p true only if second argument is also exactly zero.
 * @param r1 first number to compare.
 * @param r2 second number to compare.
 * @param eps epsilon tolerance parameter used in comparison.
 * @return @p true when @a r1 and @a r2 are almost equal, @p false otherwise.
 *
 * @see ape().
 *
 * @internal Donald E. Knuth "Art of Computer Programming" [P 4.2.2 Vol2].
 */
inline
bool ale(qreal r1, qreal r2, qreal eps = EPS)
{
	int exp1, exp2;
	std::frexp(r1, & exp1);
	std::frexp(r2, & exp2);

	return std::abs(r2 - r1) <= std::ldexp(eps, std::min(exp1, exp2));
}

/**
 * Considerably less than.
 * @param r1 first number to compare.
 * @param r2 second number to compare.
 * @param eps epsilon tolerance parameter used in comparison.
 * @return @p true when @a r1 is considerably less than @a r2, @p false otherwise.
 *
 * @internal Donald E. Knuth "Art of Computer Programming" [P 4.2.2 Vol2].
 */
inline
bool clt(qreal r1, qreal r2, qreal eps = EPS)
{
	int exp1, exp2;
	std::frexp(r1, & exp1);
	std::frexp(r2, & exp2);

	return r2 - r1 > std::ldexp(eps, std::max(exp1, exp2));
}

/**
 * Considerably greater than.
 * @param r1 first number to compare.
 * @param r2 second number to compare.
 * @param eps epsilon tolerance parameter used in comparison.
 * @return @p true when @a r1 is considerably greater than @a r2, @p false otherwise.
 *
 * @internal Donald E. Knuth "Art of Computer Programming" [P 4.2.2 Vol2].
 */
inline
bool cgt(qreal r1, qreal r2, qreal eps = EPS)
{
	int exp1, exp2;
	std::frexp(r1, & exp1);
	std::frexp(r2, & exp2);

	return r1 - r2 > std::ldexp(eps, std::max(exp1, exp2));
}

}

#endif // FUNCTIONS_HPP
<|endoftext|>


<commit_before>// Copyright 2014 BVLC and contributors.

#include <cstring>
#include <vector>

#include "gtest/gtest.h"
#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/filler.hpp"
#include "caffe/vision_layers.hpp"
#include "caffe/test/test_gradient_check_util.hpp"

#include "caffe/test/test_caffe_main.hpp"

namespace caffe {

template <typename TypeParam>
class ConvolutionLayerTest : public MultiDeviceTest<TypeParam> {
  typedef typename TypeParam::Dtype Dtype;

 protected:
  ConvolutionLayerTest()
      : blob_bottom_(new Blob<Dtype>(2, 3, 6, 4)),
        blob_bottom_2_(new Blob<Dtype>(2, 3, 6, 4)),
        blob_top_(new Blob<Dtype>()),
        blob_top_2_(new Blob<Dtype>()) {}
  virtual void SetUp() {
    // fill the values
    FillerParameter filler_param;
    filler_param.set_value(1.);
    GaussianFiller<Dtype> filler(filler_param);
    filler.Fill(this->blob_bottom_);
    filler.Fill(this->blob_bottom_2_);
    blob_bottom_vec_.push_back(blob_bottom_);
    blob_top_vec_.push_back(blob_top_);
  }

  virtual ~ConvolutionLayerTest() {
    delete blob_bottom_;
    delete blob_bottom_2_;
    delete blob_top_;
    delete blob_top_2_;
  }

  Blob<Dtype>* const blob_bottom_;
  Blob<Dtype>* const blob_bottom_2_;
  Blob<Dtype>* const blob_top_;
  Blob<Dtype>* const blob_top_2_;
  vector<Blob<Dtype>*> blob_bottom_vec_;
  vector<Blob<Dtype>*> blob_top_vec_;
};

TYPED_TEST_CASE(ConvolutionLayerTest, TestDtypesAndDevices);

TYPED_TEST(ConvolutionLayerTest, TestSetup) {
  typedef typename TypeParam::Dtype Dtype;
  LayerParameter layer_param;
  ConvolutionParameter* convolution_param =
      layer_param.mutable_convolution_param();
  convolution_param->set_kernel_size(3);
  convolution_param->set_stride(2);
  convolution_param->set_num_output(4);
  this->blob_bottom_vec_.push_back(this->blob_bottom_2_);
  this->blob_top_vec_.push_back(this->blob_top_2_);
  shared_ptr<Layer<Dtype> > layer(
      new ConvolutionLayer<Dtype>(layer_param));
  layer->SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
  EXPECT_EQ(this->blob_top_->num(), 2);
  EXPECT_EQ(this->blob_top_->channels(), 4);
  EXPECT_EQ(this->blob_top_->height(), 2);
  EXPECT_EQ(this->blob_top_->width(), 1);
  EXPECT_EQ(this->blob_top_2_->num(), 2);
  EXPECT_EQ(this->blob_top_2_->channels(), 4);
  EXPECT_EQ(this->blob_top_2_->height(), 2);
  EXPECT_EQ(this->blob_top_2_->width(), 1);
  // setting group should not change the shape
  convolution_param->set_num_output(3);
  convolution_param->set_group(3);
  layer.reset(new ConvolutionLayer<Dtype>(layer_param));
  layer->SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
  EXPECT_EQ(this->blob_top_->num(), 2);
  EXPECT_EQ(this->blob_top_->channels(), 3);
  EXPECT_EQ(this->blob_top_->height(), 2);
  EXPECT_EQ(this->blob_top_->width(), 1);
  EXPECT_EQ(this->blob_top_2_->num(), 2);
  EXPECT_EQ(this->blob_top_2_->channels(), 3);
  EXPECT_EQ(this->blob_top_2_->height(), 2);
  EXPECT_EQ(this->blob_top_2_->width(), 1);
}

TYPED_TEST(ConvolutionLayerTest, TestSimpleConvolution) {
  // We will simply see if the convolution layer carries out averaging well.
  typedef typename TypeParam::Dtype Dtype;
  shared_ptr<ConstantFiller<Dtype> > filler;
  FillerParameter filler_param;
  filler_param.set_value(1.);
  filler.reset(new ConstantFiller<Dtype>(filler_param));
  filler->Fill(this->blob_bottom_);
  filler_param.set_value(2.);
  filler.reset(new ConstantFiller<Dtype>(filler_param));
  filler->Fill(this->blob_bottom_2_);
  this->blob_bottom_vec_.push_back(this->blob_bottom_2_);
  this->blob_top_vec_.push_back(this->blob_top_2_);
  LayerParameter layer_param;
  ConvolutionParameter* convolution_param =
      layer_param.mutable_convolution_param();
  convolution_param->set_kernel_size(3);
  convolution_param->set_stride(2);
  convolution_param->set_num_output(4);
  convolution_param->mutable_weight_filler()->set_type("constant");
  convolution_param->mutable_weight_filler()->set_value(1);
  convolution_param->mutable_bias_filler()->set_type("constant");
  convolution_param->mutable_bias_filler()->set_value(0.1);
  shared_ptr<Layer<Dtype> > layer(
      new ConvolutionLayer<Dtype>(layer_param));
  layer->SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
  layer->Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
  // After the convolution, the output should all have output values 27.1
  const Dtype* top_data = this->blob_top_->cpu_data();
  for (int i = 0; i < this->blob_top_->count(); ++i) {
    EXPECT_NEAR(top_data[i], 27.1, 1e-4);
  }
  top_data = this->blob_top_2_->cpu_data();
  for (int i = 0; i < this->blob_top_2_->count(); ++i) {
    EXPECT_NEAR(top_data[i], 54.1, 1e-4);
  }
}

TYPED_TEST(ConvolutionLayerTest, TestSimpleConvolutionGroup) {
  // We will simply see if the convolution layer carries out averaging well.
  typedef typename TypeParam::Dtype Dtype;
  FillerParameter filler_param;
  filler_param.set_value(1.);
  ConstantFiller<Dtype> filler(filler_param);
  filler.Fill(this->blob_bottom_);
  Dtype* bottom_data = this->blob_bottom_->mutable_cpu_data();
  for (int n = 0; n < this->blob_bottom_->num(); ++n) {
    for (int c = 0; c < this->blob_bottom_->channels(); ++c) {
      for (int h = 0; h < this->blob_bottom_->height(); ++h) {
        for (int w = 0; w < this->blob_bottom_->width(); ++w) {
          bottom_data[this->blob_bottom_->offset(n, c, h, w)] = c;
        }
      }
    }
  }
  LayerParameter layer_param;
  ConvolutionParameter* convolution_param =
      layer_param.mutable_convolution_param();
  convolution_param->set_kernel_size(3);
  convolution_param->set_stride(2);
  convolution_param->set_num_output(3);
  convolution_param->set_group(3);
  convolution_param->mutable_weight_filler()->set_type("constant");
  convolution_param->mutable_weight_filler()->set_value(1);
  convolution_param->mutable_bias_filler()->set_type("constant");
  convolution_param->mutable_bias_filler()->set_value(0.1);
  shared_ptr<Layer<Dtype> > layer(
      new ConvolutionLayer<Dtype>(layer_param));
  layer->SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
  layer->Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
  // After the convolution, the output should all have output values 9.1
  const Dtype* top_data = this->blob_top_->cpu_data();
  for (int n = 0; n < this->blob_top_->num(); ++n) {
    for (int c = 0; c < this->blob_top_->channels(); ++c) {
      for (int h = 0; h < this->blob_top_->height(); ++h) {
        for (int w = 0; w < this->blob_top_->width(); ++w) {
          Dtype data = top_data[this->blob_top_->offset(n, c, h, w)];
          EXPECT_NEAR(data, c * 9 + 0.1, 1e-4);
        }
      }
    }
  }
}

TYPED_TEST(ConvolutionLayerTest, TestGradient) {
  typedef typename TypeParam::Dtype Dtype;
  LayerParameter layer_param;
  ConvolutionParameter* convolution_param =
      layer_param.mutable_convolution_param();
  this->blob_bottom_vec_.push_back(this->blob_bottom_2_);
  this->blob_top_vec_.push_back(this->blob_top_2_);
  convolution_param->set_kernel_size(3);
  convolution_param->set_stride(2);
  convolution_param->set_num_output(2);
  convolution_param->mutable_weight_filler()->set_type("gaussian");
  convolution_param->mutable_bias_filler()->set_type("gaussian");
  ConvolutionLayer<Dtype> layer(layer_param);
  GradientChecker<Dtype> checker(1e-2, 1e-3);
  checker.CheckGradientExhaustive(&layer, &(this->blob_bottom_vec_),
      &(this->blob_top_vec_));
}

TYPED_TEST(ConvolutionLayerTest, TestGradientGroup) {
  typedef typename TypeParam::Dtype Dtype;
  LayerParameter layer_param;
  ConvolutionParameter* convolution_param =
      layer_param.mutable_convolution_param();
  convolution_param->set_kernel_size(3);
  convolution_param->set_stride(2);
  convolution_param->set_num_output(3);
  convolution_param->set_group(3);
  convolution_param->mutable_weight_filler()->set_type("gaussian");
  convolution_param->mutable_bias_filler()->set_type("gaussian");
  ConvolutionLayer<Dtype> layer(layer_param);
  GradientChecker<Dtype> checker(1e-2, 1e-3);
  checker.CheckGradientExhaustive(&layer, &(this->blob_bottom_vec_),
      &(this->blob_top_vec_));
}

}  // namespace caffe
<commit_msg>test non-square filters by separable convolution of Sobel operator<commit_after>// Copyright 2014 BVLC and contributors.

#include <cstring>
#include <vector>

#include "gtest/gtest.h"
#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/filler.hpp"
#include "caffe/vision_layers.hpp"
#include "caffe/test/test_gradient_check_util.hpp"

#include "caffe/test/test_caffe_main.hpp"

namespace caffe {

template <typename TypeParam>
class ConvolutionLayerTest : public MultiDeviceTest<TypeParam> {
  typedef typename TypeParam::Dtype Dtype;

 protected:
  ConvolutionLayerTest()
      : blob_bottom_(new Blob<Dtype>(2, 3, 6, 4)),
        blob_bottom_2_(new Blob<Dtype>(2, 3, 6, 4)),
        blob_top_(new Blob<Dtype>()),
        blob_top_2_(new Blob<Dtype>()) {}
  virtual void SetUp() {
    // fill the values
    FillerParameter filler_param;
    filler_param.set_value(1.);
    GaussianFiller<Dtype> filler(filler_param);
    filler.Fill(this->blob_bottom_);
    filler.Fill(this->blob_bottom_2_);
    blob_bottom_vec_.push_back(blob_bottom_);
    blob_top_vec_.push_back(blob_top_);
  }

  virtual ~ConvolutionLayerTest() {
    delete blob_bottom_;
    delete blob_bottom_2_;
    delete blob_top_;
    delete blob_top_2_;
  }

  Blob<Dtype>* const blob_bottom_;
  Blob<Dtype>* const blob_bottom_2_;
  Blob<Dtype>* const blob_top_;
  Blob<Dtype>* const blob_top_2_;
  vector<Blob<Dtype>*> blob_bottom_vec_;
  vector<Blob<Dtype>*> blob_top_vec_;
};

TYPED_TEST_CASE(ConvolutionLayerTest, TestDtypesAndDevices);

TYPED_TEST(ConvolutionLayerTest, TestSetup) {
  typedef typename TypeParam::Dtype Dtype;
  LayerParameter layer_param;
  ConvolutionParameter* convolution_param =
      layer_param.mutable_convolution_param();
  convolution_param->set_kernel_size(3);
  convolution_param->set_stride(2);
  convolution_param->set_num_output(4);
  this->blob_bottom_vec_.push_back(this->blob_bottom_2_);
  this->blob_top_vec_.push_back(this->blob_top_2_);
  shared_ptr<Layer<Dtype> > layer(
      new ConvolutionLayer<Dtype>(layer_param));
  layer->SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
  EXPECT_EQ(this->blob_top_->num(), 2);
  EXPECT_EQ(this->blob_top_->channels(), 4);
  EXPECT_EQ(this->blob_top_->height(), 2);
  EXPECT_EQ(this->blob_top_->width(), 1);
  EXPECT_EQ(this->blob_top_2_->num(), 2);
  EXPECT_EQ(this->blob_top_2_->channels(), 4);
  EXPECT_EQ(this->blob_top_2_->height(), 2);
  EXPECT_EQ(this->blob_top_2_->width(), 1);
  // setting group should not change the shape
  convolution_param->set_num_output(3);
  convolution_param->set_group(3);
  layer.reset(new ConvolutionLayer<Dtype>(layer_param));
  layer->SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
  EXPECT_EQ(this->blob_top_->num(), 2);
  EXPECT_EQ(this->blob_top_->channels(), 3);
  EXPECT_EQ(this->blob_top_->height(), 2);
  EXPECT_EQ(this->blob_top_->width(), 1);
  EXPECT_EQ(this->blob_top_2_->num(), 2);
  EXPECT_EQ(this->blob_top_2_->channels(), 3);
  EXPECT_EQ(this->blob_top_2_->height(), 2);
  EXPECT_EQ(this->blob_top_2_->width(), 1);
}

TYPED_TEST(ConvolutionLayerTest, TestSimpleConvolution) {
  // We will simply see if the convolution layer carries out averaging well.
  typedef typename TypeParam::Dtype Dtype;
  shared_ptr<ConstantFiller<Dtype> > filler;
  FillerParameter filler_param;
  filler_param.set_value(1.);
  filler.reset(new ConstantFiller<Dtype>(filler_param));
  filler->Fill(this->blob_bottom_);
  filler_param.set_value(2.);
  filler.reset(new ConstantFiller<Dtype>(filler_param));
  filler->Fill(this->blob_bottom_2_);
  this->blob_bottom_vec_.push_back(this->blob_bottom_2_);
  this->blob_top_vec_.push_back(this->blob_top_2_);
  LayerParameter layer_param;
  ConvolutionParameter* convolution_param =
      layer_param.mutable_convolution_param();
  convolution_param->set_kernel_size(3);
  convolution_param->set_stride(2);
  convolution_param->set_num_output(4);
  convolution_param->mutable_weight_filler()->set_type("constant");
  convolution_param->mutable_weight_filler()->set_value(1);
  convolution_param->mutable_bias_filler()->set_type("constant");
  convolution_param->mutable_bias_filler()->set_value(0.1);
  shared_ptr<Layer<Dtype> > layer(
      new ConvolutionLayer<Dtype>(layer_param));
  layer->SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
  layer->Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
  // After the convolution, the output should all have output values 27.1
  const Dtype* top_data = this->blob_top_->cpu_data();
  for (int i = 0; i < this->blob_top_->count(); ++i) {
    EXPECT_NEAR(top_data[i], 27.1, 1e-4);
  }
  top_data = this->blob_top_2_->cpu_data();
  for (int i = 0; i < this->blob_top_2_->count(); ++i) {
    EXPECT_NEAR(top_data[i], 54.1, 1e-4);
  }
}

TYPED_TEST(ConvolutionLayerTest, TestSimpleConvolutionGroup) {
  // We will simply see if the convolution layer carries out averaging well.
  typedef typename TypeParam::Dtype Dtype;
  FillerParameter filler_param;
  filler_param.set_value(1.);
  ConstantFiller<Dtype> filler(filler_param);
  filler.Fill(this->blob_bottom_);
  Dtype* bottom_data = this->blob_bottom_->mutable_cpu_data();
  for (int n = 0; n < this->blob_bottom_->num(); ++n) {
    for (int c = 0; c < this->blob_bottom_->channels(); ++c) {
      for (int h = 0; h < this->blob_bottom_->height(); ++h) {
        for (int w = 0; w < this->blob_bottom_->width(); ++w) {
          bottom_data[this->blob_bottom_->offset(n, c, h, w)] = c;
        }
      }
    }
  }
  LayerParameter layer_param;
  ConvolutionParameter* convolution_param =
      layer_param.mutable_convolution_param();
  convolution_param->set_kernel_size(3);
  convolution_param->set_stride(2);
  convolution_param->set_num_output(3);
  convolution_param->set_group(3);
  convolution_param->mutable_weight_filler()->set_type("constant");
  convolution_param->mutable_weight_filler()->set_value(1);
  convolution_param->mutable_bias_filler()->set_type("constant");
  convolution_param->mutable_bias_filler()->set_value(0.1);
  shared_ptr<Layer<Dtype> > layer(
      new ConvolutionLayer<Dtype>(layer_param));
  layer->SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
  layer->Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
  // After the convolution, the output should all have output values 9.1
  const Dtype* top_data = this->blob_top_->cpu_data();
  for (int n = 0; n < this->blob_top_->num(); ++n) {
    for (int c = 0; c < this->blob_top_->channels(); ++c) {
      for (int h = 0; h < this->blob_top_->height(); ++h) {
        for (int w = 0; w < this->blob_top_->width(); ++w) {
          Dtype data = top_data[this->blob_top_->offset(n, c, h, w)];
          EXPECT_NEAR(data, c * 9 + 0.1, 1e-4);
        }
      }
    }
  }
}

TYPED_TEST(ConvolutionLayerTest, TestSobelConvolution) {
  // Test separable convolution by computing the Sobel operator
  // as a single filter then comparing the result
  // as the convolution of two rectangular filters.
  typedef typename TypeParam::Dtype Dtype;
  // Fill bottoms with identical Gaussian noise.
  shared_ptr<GaussianFiller<Dtype> > filler;
  FillerParameter filler_param;
  filler_param.set_value(1.);
  filler.reset(new GaussianFiller<Dtype>(filler_param));
  filler->Fill(this->blob_bottom_);
  this->blob_bottom_2_->CopyFrom(*this->blob_bottom_);
  // Compute Sobel G_x operator as 3 x 3 convolution.
  LayerParameter layer_param;
  ConvolutionParameter* convolution_param =
      layer_param.mutable_convolution_param();
  convolution_param->set_kernel_size(3);
  convolution_param->set_stride(2);
  convolution_param->set_num_output(1);
  convolution_param->set_bias_term(false);
  shared_ptr<Layer<Dtype> > layer(
      new ConvolutionLayer<Dtype>(layer_param));
  layer->blobs().resize(1);
  layer->blobs()[0].reset(new Blob<Dtype>(1, 3, 3, 3));
  Dtype* weights = layer->blobs()[0]->mutable_cpu_data();
  for (int c = 0; c < 3; ++c) {
    int i = c * 9;  // 3 x 3 filter
    weights[i +  0] = -1;
    weights[i +  1] =  0;
    weights[i +  2] =  1;
    weights[i +  3] = -2;
    weights[i +  4] =  0;
    weights[i +  5] =  2;
    weights[i +  6] = -1;
    weights[i +  7] =  0;
    weights[i +  8] =  1;
  }
  layer->SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
  layer->Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
  // Compute Sobel G_x operator as separable 3 x 1 and 1 x 3 convolutions.
  // (1) the [1 2 1] column filter
  vector<Blob<Dtype>*> sep_blob_bottom_vec;
  vector<Blob<Dtype>*> sep_blob_top_vec;
  shared_ptr<Blob<Dtype> > blob_sep(new Blob<Dtype>());
  sep_blob_bottom_vec.push_back(this->blob_bottom_2_);
  sep_blob_top_vec.push_back(this->blob_top_2_);
  convolution_param->clear_kernel_size();
  convolution_param->clear_stride();
  convolution_param->set_kernel_h(3);
  convolution_param->set_kernel_w(1);
  convolution_param->set_stride_h(2);
  convolution_param->set_stride_w(1);
  convolution_param->set_num_output(1);
  convolution_param->set_bias_term(false);
  layer.reset(new ConvolutionLayer<Dtype>(layer_param));
  layer->blobs().resize(1);
  layer->blobs()[0].reset(new Blob<Dtype>(1, 3, 3, 1));
  Dtype* weights_1 = layer->blobs()[0]->mutable_cpu_data();
  for (int c = 0; c < 3; ++c) {
    int i = c * 3;  // 3 x 1 filter
    weights_1[i +  0] = 1;
    weights_1[i +  1] = 2;
    weights_1[i +  2] = 1;
  }
  layer->SetUp(sep_blob_bottom_vec, &(sep_blob_top_vec));
  layer->Forward(sep_blob_bottom_vec, &(sep_blob_top_vec));
  // (2) the [-1 0 1] row filter
  blob_sep->CopyFrom(*this->blob_top_2_, false, true);
  sep_blob_bottom_vec.clear();
  sep_blob_bottom_vec.push_back(blob_sep.get());
  convolution_param->set_kernel_h(1);
  convolution_param->set_kernel_w(3);
  convolution_param->set_stride_h(1);
  convolution_param->set_stride_w(2);
  convolution_param->set_num_output(1);
  convolution_param->set_bias_term(false);
  layer.reset(new ConvolutionLayer<Dtype>(layer_param));
  layer->blobs().resize(1);
  layer->blobs()[0].reset(new Blob<Dtype>(1, 3, 1, 3));
  Dtype* weights_2 = layer->blobs()[0]->mutable_cpu_data();
  for (int c = 0; c < 3; ++c) {
    int i = c * 3;  // 1 x 3 filter
    weights_2[i +  0] = -1;
    weights_2[i +  1] =  0;
    weights_2[i +  2] =  1;
  }
  layer->SetUp(sep_blob_bottom_vec, &(sep_blob_top_vec));
  layer->Forward(sep_blob_bottom_vec, &(sep_blob_top_vec));
  // Test equivalence of full and separable filters.
  const Dtype* top_data = this->blob_top_->cpu_data();
  const Dtype* sep_top_data = this->blob_top_2_->cpu_data();
  for (int i = 0; i < this->blob_top_->count(); ++i) {
    EXPECT_NEAR(top_data[i], sep_top_data[i], 1e-4);
  }
}

TYPED_TEST(ConvolutionLayerTest, TestGradient) {
  typedef typename TypeParam::Dtype Dtype;
  LayerParameter layer_param;
  ConvolutionParameter* convolution_param =
      layer_param.mutable_convolution_param();
  this->blob_bottom_vec_.push_back(this->blob_bottom_2_);
  this->blob_top_vec_.push_back(this->blob_top_2_);
  convolution_param->set_kernel_size(3);
  convolution_param->set_stride(2);
  convolution_param->set_num_output(2);
  convolution_param->mutable_weight_filler()->set_type("gaussian");
  convolution_param->mutable_bias_filler()->set_type("gaussian");
  ConvolutionLayer<Dtype> layer(layer_param);
  GradientChecker<Dtype> checker(1e-2, 1e-3);
  checker.CheckGradientExhaustive(&layer, &(this->blob_bottom_vec_),
      &(this->blob_top_vec_));
}

TYPED_TEST(ConvolutionLayerTest, TestGradientGroup) {
  typedef typename TypeParam::Dtype Dtype;
  LayerParameter layer_param;
  ConvolutionParameter* convolution_param =
      layer_param.mutable_convolution_param();
  convolution_param->set_kernel_size(3);
  convolution_param->set_stride(2);
  convolution_param->set_num_output(3);
  convolution_param->set_group(3);
  convolution_param->mutable_weight_filler()->set_type("gaussian");
  convolution_param->mutable_bias_filler()->set_type("gaussian");
  ConvolutionLayer<Dtype> layer(layer_param);
  GradientChecker<Dtype> checker(1e-2, 1e-3);
  checker.CheckGradientExhaustive(&layer, &(this->blob_bottom_vec_),
      &(this->blob_top_vec_));
}

}  // namespace caffe
<|endoftext|>


<commit_before>//
//  partlistvisitor.cpp
//  libmusicxml2
//
//  Created by Arshia Cont on 05/01/17.
//
//

#include <algorithm>

#include "partlistvisitor.h"

#include "rational.h"
#include "xml_tree_browser.h"
#include "tree_browser.h"

using namespace std;

namespace MusicXML2
{
    partlistvisitor::partlistvisitor() : fPartGroupIncrementer(0), staffCreatorCounter(1)
    {
    }

    partGroup* partlistvisitor::find_first_of_partID_inGroup(std::string partID)
    {
        // search if this part ID exists in any grouping
        // Guido Limitation: One \accol tag per staff ONLY (for nested definitions)
        // IDEA: Treat the FIRST occurence of partID in grouping and get rid of it.
        std::map<int, partGroup>::iterator partGroupIt;
        for (partGroupIt=fPartGroups.begin();
             partGroupIt != fPartGroups.end();
             partGroupIt++)
        {
            if (partGroupIt->second.visited == false) {
                if (std::find(partGroupIt->second.partIDs.begin()
                              , partGroupIt->second.partIDs.end(),
                              partID) != partGroupIt->second.partIDs.end() )
                {
                    // this partID is in group number partGroupIt->first
                    //cerr << "\t ID found in group " << partGroupIt->first <<" "<<endl;
                    break;

                }
            }
        }

        if (partGroupIt != fPartGroups.end())
        {
            return &partGroupIt->second;
        }

        return NULL;
    }

    void partlistvisitor::partID2range(partGroup &pGroup)
    {
        std::vector<int> staves;
        for (size_t i=0; i<pGroup.partIDs.size();i++)
        {
            staves.push_back(part2staffmap[pGroup.partIDs[i]]);
        }
        std::vector<int>::iterator rangeEnd = std::max_element(staves.begin(), staves.end());
        std::vector<int>::iterator rangeBegin = std::min_element(staves.begin(), staves.begin());

        stringstream rangeStream;
        rangeStream << "\""<< (*rangeBegin)<<"-"<<(*rangeEnd)<<"\"";
        pGroup.guidoRange = rangeStream.str();
        pGroup.guidoRangeStart = *rangeBegin;
        pGroup.guidoRangeStop = *rangeEnd;
    }

    bool partlistvisitor::checkLonelyBarFormat(int staffID)
    {
        std::map<int, partGroup>::iterator partGroupIt;
        for (partGroupIt=fPartGroups.begin();
             partGroupIt != fPartGroups.end();
             partGroupIt++)
        {
            if (partGroupIt->second.barlineGrouping == true)
            {
                // see if this staff is in range
                if ( (staffID>= partGroupIt->second.guidoRangeStart)&&(staffID<=partGroupIt->second.guidoRangeStop))
                {
                    return false;
                }
            }
        }

        return true;
    }

    /// Visitors

    void partlistvisitor::visitStart ( S_part_group& elt )
    {
        int partGroupNumber = elt->getAttributeIntValue("number", 0);
        /// IMPORTANT NOTE: the number attribute is NOT sequential and can be repeated! So we need to do further book-keeping.
        std::string partGroupType = elt->getAttributeValue("type");

        if (partGroupType=="start")
        {
            int groupIndex = fPartGroupIncrementer;
            fPartGroups[groupIndex].xmlGroupNumber = partGroupNumber;
            if (elt->getValue(k_group_symbol)=="bracket")
            {
                fPartGroups[groupIndex].bracket = true;
            } else
                fPartGroups[groupIndex].bracket = false;

            if (elt->getValue(k_group_barline)=="yes")
            {
                fPartGroups[groupIndex].barlineGrouping = true;
            } else
                fPartGroups[groupIndex].barlineGrouping = false;

            // Add optional names
            fPartGroups[groupIndex].fGroupName = elt->getValue(k_group_name);
            fPartGroups[groupIndex].visited = false;

            fCurrentPartGroupIndex.push_back(groupIndex);
            fPartGroupIncrementer++;
            //cerr << "Started group " << partGroupNumber << " index " << groupIndex<<" (" << fCurrentPartGroupIndex.size() << ")" << endl;
        }else
            if (partGroupType=="stop")
            {
                // Erase the INDEX whose xmlGroupNumber is equal to partGroupNumber
                std::vector<int>::iterator ito;
                for (ito = fCurrentPartGroupIndex.begin(); ito < fCurrentPartGroupIndex.end(); ito++)
                {
                    if (fPartGroups[*ito].xmlGroupNumber == partGroupNumber)
                        break;
                }

                // calculate Guido Range and set
                partID2range(fPartGroups[*ito]);

                // Do Erase
                if (ito != fCurrentPartGroupIndex.end())
                {
                    fCurrentPartGroupIndex.erase(ito);
                }else
                    cerr << "Something is really wrong in S_PART_GROUP visitor!" << endl;
            }
    }

    void partlistvisitor::visitStart( S_score_part& elt)
    {
        std::string PartID = elt->getAttributeValue("id");
        part2staffmap[PartID] = staffCreatorCounter;
        staffCreatorCounter++;

        fPartHeaders[PartID].fPartName = elt->getValue(k_part_name);
        fPartHeaders[PartID].fPartNameAbbr = elt->getValue(k_part_abbreviation);

        // add groupings if any
        if (fCurrentPartGroupIndex.size())
        {
            for (size_t ind=0; ind < fCurrentPartGroupIndex.size(); ind++)
            {
                fPartGroups[fCurrentPartGroupIndex[ind]].partIDs.push_back(PartID);
            }
        }
    }

}
<commit_msg>fix crash bug in partID2range<commit_after>//
//  partlistvisitor.cpp
//  libmusicxml2
//
//  Created by Arshia Cont on 05/01/17.
//
//

#include <algorithm>

#include "partlistvisitor.h"

#include "rational.h"
#include "xml_tree_browser.h"
#include "tree_browser.h"

using namespace std;

namespace MusicXML2
{
    partlistvisitor::partlistvisitor() : fPartGroupIncrementer(0), staffCreatorCounter(1)
    {
    }

    partGroup* partlistvisitor::find_first_of_partID_inGroup(std::string partID)
    {
        // search if this part ID exists in any grouping
        // Guido Limitation: One \accol tag per staff ONLY (for nested definitions)
        // IDEA: Treat the FIRST occurence of partID in grouping and get rid of it.
        std::map<int, partGroup>::iterator partGroupIt;
        for (partGroupIt=fPartGroups.begin();
             partGroupIt != fPartGroups.end();
             partGroupIt++)
        {
            if (partGroupIt->second.visited == false) {
                if (std::find(partGroupIt->second.partIDs.begin()
                              , partGroupIt->second.partIDs.end(),
                              partID) != partGroupIt->second.partIDs.end() )
                {
                    // this partID is in group number partGroupIt->first
                    //cerr << "\t ID found in group " << partGroupIt->first <<" "<<endl;
                    break;

                }
            }
        }

        if (partGroupIt != fPartGroups.end())
        {
            return &partGroupIt->second;
        }

        return NULL;
    }

    void partlistvisitor::partID2range(partGroup &pGroup)
    {
        std::vector<int> staves;
        for (size_t i=0; i<pGroup.partIDs.size();i++)
        {
            staves.push_back(part2staffmap[pGroup.partIDs[i]]);
        }
		if (staves.empty()) return;

        std::vector<int>::iterator rangeEnd = std::max_element(staves.begin(), staves.end());
        std::vector<int>::iterator rangeBegin = std::min_element(staves.begin(), staves.begin());

        stringstream rangeStream;
        rangeStream << "\"" << (*rangeBegin) << "-" << (*rangeEnd) << "\"";
        pGroup.guidoRange = rangeStream.str();
        pGroup.guidoRangeStart = *rangeBegin;
        pGroup.guidoRangeStop = *rangeEnd;
    }

    bool partlistvisitor::checkLonelyBarFormat(int staffID)
    {
        std::map<int, partGroup>::iterator partGroupIt;
        for (partGroupIt=fPartGroups.begin();
             partGroupIt != fPartGroups.end();
             partGroupIt++)
        {
            if (partGroupIt->second.barlineGrouping == true)
            {
                // see if this staff is in range
                if ( (staffID>= partGroupIt->second.guidoRangeStart)&&(staffID<=partGroupIt->second.guidoRangeStop))
                {
                    return false;
                }
            }
        }

        return true;
    }

    /// Visitors

    void partlistvisitor::visitStart ( S_part_group& elt )
    {
        int partGroupNumber = elt->getAttributeIntValue("number", 0);
        /// IMPORTANT NOTE: the number attribute is NOT sequential and can be repeated! So we need to do further book-keeping.
        std::string partGroupType = elt->getAttributeValue("type");

        if (partGroupType=="start")
        {
            int groupIndex = fPartGroupIncrementer;
            fPartGroups[groupIndex].xmlGroupNumber = partGroupNumber;
            if (elt->getValue(k_group_symbol)=="bracket")
            {
                fPartGroups[groupIndex].bracket = true;
            } else
                fPartGroups[groupIndex].bracket = false;

            if (elt->getValue(k_group_barline)=="yes")
            {
                fPartGroups[groupIndex].barlineGrouping = true;
            } else
                fPartGroups[groupIndex].barlineGrouping = false;

            // Add optional names
            fPartGroups[groupIndex].fGroupName = elt->getValue(k_group_name);
            fPartGroups[groupIndex].visited = false;

            fCurrentPartGroupIndex.push_back(groupIndex);
            fPartGroupIncrementer++;
            //cerr << "Started group " << partGroupNumber << " index " << groupIndex<<" (" << fCurrentPartGroupIndex.size() << ")" << endl;
        }else
            if (partGroupType=="stop")
            {
                // Erase the INDEX whose xmlGroupNumber is equal to partGroupNumber
                std::vector<int>::iterator ito;
                for (ito = fCurrentPartGroupIndex.begin(); ito < fCurrentPartGroupIndex.end(); ito++)
                {
                    if (fPartGroups[*ito].xmlGroupNumber == partGroupNumber)
                        break;
                }

                // calculate Guido Range and set
                partID2range(fPartGroups[*ito]);

                // Do Erase
                if (ito != fCurrentPartGroupIndex.end())
                {
                    fCurrentPartGroupIndex.erase(ito);
                }else
                    cerr << "Something is really wrong in S_PART_GROUP visitor!" << endl;
            }
    }

    void partlistvisitor::visitStart( S_score_part& elt)
    {
        std::string PartID = elt->getAttributeValue("id");
        part2staffmap[PartID] = staffCreatorCounter;
        staffCreatorCounter++;

        fPartHeaders[PartID].fPartName = elt->getValue(k_part_name);
        fPartHeaders[PartID].fPartNameAbbr = elt->getValue(k_part_abbreviation);

        // add groupings if any
        if (fCurrentPartGroupIndex.size())
        {
            for (size_t ind=0; ind < fCurrentPartGroupIndex.size(); ind++)
            {
                fPartGroups[fCurrentPartGroupIndex[ind]].partIDs.push_back(PartID);
            }
        }
    }

}
<|endoftext|>


<commit_before>/*
 * VehicleExtraProperties.cpp
 *
 *  Created on: Apr 25, 2015
 *      Author: arman
 */

#include "VehicleExtraProperties.h"

// Arman : maybe too many includes
#include "core/ChStream.h"

//#include "chrono_parallel/lcp/ChLcpSystemDescriptorParallel.h"
//#include "chrono_parallel/collision/ChCNarrowphaseRUtils.h"
#include "chrono_vehicle/ChVehicleModelData.h"

int chassisFam = 2;
int tireFam = 3;

//#include "hmmwvParams.h"

using namespace chrono;
using namespace collision;

// Tire Coefficient of friction
float mu_t = 0.8;

// Callback class for providing driver inputs.
MyDriverInputs::MyDriverInputs(double delay) : m_delay(delay) {}
void MyDriverInputs::onCallback(double time, double& throttle, double& steering, double& braking) {
	throttle = 0;
	steering = 0;
	braking = 0;

	double eff_time = time - m_delay;

	// Do not generate any driver inputs for a duration equal to m_delay.
	if (eff_time < 0)
		return;

	if (eff_time > 0.2)
		throttle = 1.0;
	else if (eff_time > 0.1)
		throttle = 10 * (eff_time - 0.1);
}

// Callback class for specifying rigid tire contact model.
// This version uses cylindrical contact shapes.
void MyCylindricalTire::onCallback(ChSharedPtr<ChBody> wheelBody, double radius, double width) {
	wheelBody->ChangeCollisionModel(new collision::ChCollisionModelParallel);

	wheelBody->GetCollisionModel()->ClearModel();
	wheelBody->GetCollisionModel()->AddCylinder(0.46, 0.46, width / 2);
	wheelBody->GetCollisionModel()->BuildModel();

	wheelBody->GetMaterialSurface()->SetFriction(mu_t);
}

// Callback class for specifying rigid tire contact model.
// This version uses a collection of convex contact shapes (meshes).
MyLuggedTire::MyLuggedTire() {
	std::string lugged_file("hmmwv/lugged_wheel_section.obj");
	geometry::ChTriangleMeshConnected lugged_mesh;
	utils::LoadConvexMesh(vehicle::GetDataFile(lugged_file), lugged_mesh, lugged_convex);
	num_hulls = lugged_convex.GetHullCount();
}
void MyLuggedTire::onCallback(ChSharedPtr<ChBody> wheelBody, double radius, double width) {
	wheelBody->ChangeCollisionModel(new collision::ChCollisionModelParallel);

	ChCollisionModelParallel* coll_model = (ChCollisionModelParallel*)wheelBody->GetCollisionModel();
	coll_model->ClearModel();

	// Assemble the tire contact from 15 segments, properly offset.
	// Each segment is further decomposed in convex hulls.
	for (int iseg = 0; iseg < 15; iseg++) {
		ChQuaternion<> rot = Q_from_AngAxis(iseg * 24 * CH_C_DEG_TO_RAD, VECT_Y);
		for (int ihull = 0; ihull < num_hulls; ihull++) {
			std::vector<ChVector<> > convexhull;
			lugged_convex.GetConvexHullResult(ihull, convexhull);
			coll_model->AddConvexHull(convexhull, VNULL, rot);
		}
	}

	// Add a cylinder to represent the wheel hub.
	coll_model->AddCylinder(0.223, 0.223, 0.126);

	coll_model->BuildModel();

	wheelBody->GetMaterialSurface()->SetFriction(mu_t);
}

// Callback class for specifying chassis contact model.
// This version uses a box representing the chassis.
// In addition, this version overrides the visualization assets of the provided
// chassis body with the collision meshes.
void MyChassisBoxModel_vis::onCallback(ChSharedPtr<ChBodyAuxRef> chassisBody) {
  // Clear any existing assets (will be overriden)

  chassisBody->GetCollisionModel()->ClearModel();
  ChVector<> chLoc = ChVector<>(0, 0, 0);
  //    ChVector<> chLoc = chassisBody->GetFrame_REF_to_COG().GetPos();
  chassisBody->GetCollisionModel()->AddBox(size.x, size.y, size.z, chLoc, rot);
  //    utils::AddBoxGeometry(
  //        chassisBody.get_ptr(), ChVector<>(1, .5, .05), ChVector<>(0, 0, 0), ChQuaternion<>(1, 0, 0, 0), true);
  chassisBody->GetCollisionModel()->SetFamily(chassisFam);
  chassisBody->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(tireFam);
  chassisBody->GetCollisionModel()->BuildModel();
  chassisBody->GetMaterialSurface()->SetFriction(mu_t);

  chassisBody->GetAssets().clear();
  ChSharedPtr<ChBoxShape> box(new ChBoxShape);
  box->GetBoxGeometry().Size = size;
  box->Rot = rot;
  chassisBody->GetAssets().push_back(box);
}

void MyChassisBoxModel_vis::SetAttributes(const ChVector<>& otherSize,
                           const ChQuaternion<>& otherRot,
                           const ChVector<>& otherLoc) {
  size = otherSize;
  rot = otherRot;
  loc = otherLoc;
}

// Callback class for specifying chassis contact model.
// This version uses a sphere representing the chassis.
// In addition, this version overrides the visualization assets of the provided
// chassis body with the collision meshes.
void MyChassisSphereModel_vis::onCallback(ChSharedPtr<ChBodyAuxRef> chassisBody) {
  // Clear any existing assets (will be overriden)

  chassisBody->GetCollisionModel()->ClearModel();
  ChVector<> chLoc = ChVector<>(0, 0, 0);
//        ChVector<> chLoc = chassisBody->GetFrame_REF_to_COG().GetPos();
  chassisBody->GetCollisionModel()->AddSphere(rad, chLoc);
  //    utils::AddBoxGeometry(
  //        chassisBody.get_ptr(), ChVector<>(1, .5, .05), ChVector<>(0, 0, 0), ChQuaternion<>(1, 0, 0, 0), true);
  chassisBody->GetCollisionModel()->SetFamily(chassisFam);
  chassisBody->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(tireFam);
  chassisBody->GetCollisionModel()->BuildModel();
  chassisBody->GetMaterialSurface()->SetFriction(mu_t);

  chassisBody->GetAssets().clear();
  ChSharedPtr<ChSphereShape> sphere(new ChSphereShape);
  sphere->GetSphereGeometry().rad = rad;
  chassisBody->GetAssets().push_back(sphere);
}

void MyChassisSphereModel_vis::SetAttributes(double otherRad,
                           const ChQuaternion<>& otherRot,
                           const ChVector<>& otherLoc) {
  rad = otherRad;
  rot = otherRot;
  loc = otherLoc;
}

// Callback class for specifying chassis contact model.
// This version uses a convex decomposition of an obj representing the chassis.
MyChassisSimpleConvexMesh::MyChassisSimpleConvexMesh() :
	pos(chrono::ChVector<>(0, 0, 0)) , rot( chrono::ChQuaternion<>(1, 0, 0, 0)) {
  //    std::string chassis_obj_file("hmmwv/lugged_wheel_section.obj");
  //    std::string chassis_obj_file("hmmwv/lugged_wheel.obj");
  //    std::string chassis_obj_file("hmmwv/myHumvee.obj");
//  chassis_obj_file = std::string("hmmwv/myHumvee1.obj");
	chassis_obj_file = std::string("hmmwv/hmmwv_chassis_simple.obj");

  utils::LoadConvexMesh(vehicle::GetDataFile(chassis_obj_file), chassis_mesh, chassis_convex);
}

void MyChassisSimpleConvexMesh::onCallback(ChSharedPtr<ChBodyAuxRef> chassisBody) {
  ChVector<> chLoc = ChVector<>(0, 0, 0);  // chassisBody->GetFrame_REF_to_COG().GetPos();
  chassisBody->GetCollisionModel()->ClearModel();
  //    utils::AddConvexCollisionModel(chassisBody, chassis_mesh, chassis_convex, chLoc, ChQuaternion<>(1, 0, 0, 0),
  //    false);

  // **************************
  ChSharedPtr<ChBody> body = chassisBody;
  geometry::ChTriangleMeshConnected& convex_mesh = chassis_mesh;
  ChConvexDecompositionHACDv2& convex_shape = chassis_convex;
  ChConvexDecomposition* used_decomposition = &convex_shape;

  //*****
  int hull_count = used_decomposition->GetHullCount();

  for (int c = 0; c < hull_count; c++) {
    std::vector<ChVector<double> > convexhull;
    used_decomposition->GetConvexHullResult(c, convexhull);

    ((collision::ChCollisionModelParallel*)body->GetCollisionModel())->AddConvexHull(convexhull, chLoc, rot);
  }
  chassisBody->GetCollisionModel()->SetFamily(chassisFam);
//    printf("chassis family %d \n", chassisBody->GetCollisionModel()->GetFamily());
  chassisBody->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(tireFam);
  chassisBody->GetCollisionModel()->BuildModel();

  // **************************

  //        chassisBody->RecomputeCollisionModel();
  //        chassisBody->SetCollide(false);

  chassisBody->GetMaterialSurface()->SetFriction(mu_t);
}

// Callback class for specifying chassis contact model.
// This version uses a triangular given in an obj representing the chassis.
// In addition, this version overrides the visualization assets of the provided
// chassis body with the collision meshes.
MyChassisSimpleTriMesh_vis::MyChassisSimpleTriMesh_vis() :
	pos(chrono::ChVector<>(0, 0, 0)) , rot( chrono::ChQuaternion<>(1, 0, 0, 0)) {
//	chassis_obj_file = std::string("hmmwv/myHumvee1.obj");
	chassis_obj_file = std::string("hmmwv/hmmwv_chassis_simple.obj");
}

void MyChassisSimpleTriMesh_vis::onCallback(ChSharedPtr<ChBodyAuxRef> chassisBody) {
  // Clear any existing assets (will be overriden)
  const std::string mesh_name("chassis");

  chassisBody->GetAssets().clear();
  //    ChVector<> chLoc = ChVector<>(0,0,0);//chassisBody->GetFrame_REF_to_COG().GetPos();

  chassisBody->GetCollisionModel()->ClearModel();
  //    utils::AddTriangleMeshGeometry(chassisBody.get_ptr(), vehicle::GetDataFile(chassis_obj_file), mesh_name, pos,
  //    rot, true);

      ChVector<> chLoc = ChVector<>(0, 0, 0);  // chassisBody->GetFrame_REF_to_COG().GetPos();
//    ChVector<> chLoc = chassisBody->GetFrame_REF_to_COG().GetPos();

  // *** here
  std::string obj_filename = vehicle::GetDataFile(chassis_obj_file);
  const std::string& name = mesh_name;
  ChBody* body = chassisBody.get_ptr();
  geometry::ChTriangleMeshConnected trimesh;
  trimesh.LoadWavefrontMesh(obj_filename, false, false);

  for (int i = 0; i < trimesh.m_vertices.size(); i++)
    trimesh.m_vertices[i] = pos + rot.Rotate(trimesh.m_vertices[i]);

  body->GetCollisionModel()->AddTriangleMesh(trimesh, false, false, chLoc);

  if (true) {
    ChSharedPtr<ChTriangleMeshShape> trimesh_shape(new ChTriangleMeshShape);
    trimesh_shape->SetMesh(trimesh);
    trimesh_shape->SetName(name);
    trimesh_shape->Pos = ChVector<>(0, 0, 0);
    trimesh_shape->Rot = ChQuaternion<>(1, 0, 0, 0);
    body->GetAssets().push_back(trimesh_shape);
  }
  // *** to here
  chassisBody->GetCollisionModel()->SetFamily(chassisFam);
  chassisBody->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(tireFam);
  chassisBody->GetCollisionModel()->BuildModel();

  chassisBody->GetMaterialSurface()->SetFriction(mu_t);
}

<commit_msg>collision model need to be set for contact geometries<commit_after>/*
 * VehicleExtraProperties.cpp
 *
 *  Created on: Apr 25, 2015
 *      Author: arman
 */

#include "VehicleExtraProperties.h"

// Arman : maybe too many includes
#include "core/ChStream.h"

//#include "chrono_parallel/lcp/ChLcpSystemDescriptorParallel.h"
//#include "chrono_parallel/collision/ChCNarrowphaseRUtils.h"
#include "chrono_vehicle/ChVehicleModelData.h"

int chassisFam = 2;
int tireFam = 3;

//#include "hmmwvParams.h"

using namespace chrono;
using namespace collision;

// Tire Coefficient of friction
float mu_t = 0.8;

// Callback class for providing driver inputs.
MyDriverInputs::MyDriverInputs(double delay) : m_delay(delay) {}
void MyDriverInputs::onCallback(double time, double& throttle, double& steering, double& braking) {
	throttle = 0;
	steering = 0;
	braking = 0;

	double eff_time = time - m_delay;

	// Do not generate any driver inputs for a duration equal to m_delay.
	if (eff_time < 0)
		return;

	if (eff_time > 0.2)
		throttle = 1.0;
	else if (eff_time > 0.1)
		throttle = 10 * (eff_time - 0.1);
}

// Callback class for specifying rigid tire contact model.
// This version uses cylindrical contact shapes.
void MyCylindricalTire::onCallback(ChSharedPtr<ChBody> wheelBody, double radius, double width) {
	wheelBody->ChangeCollisionModel(new collision::ChCollisionModelParallel);

	wheelBody->GetCollisionModel()->ClearModel();
	wheelBody->GetCollisionModel()->AddCylinder(0.46, 0.46, width / 2);
	wheelBody->GetCollisionModel()->BuildModel();

	wheelBody->GetMaterialSurface()->SetFriction(mu_t);
}

// Callback class for specifying rigid tire contact model.
// This version uses a collection of convex contact shapes (meshes).
MyLuggedTire::MyLuggedTire() {
	std::string lugged_file("hmmwv/lugged_wheel_section.obj");
	geometry::ChTriangleMeshConnected lugged_mesh;
	utils::LoadConvexMesh(vehicle::GetDataFile(lugged_file), lugged_mesh, lugged_convex);
	num_hulls = lugged_convex.GetHullCount();
}
void MyLuggedTire::onCallback(ChSharedPtr<ChBody> wheelBody, double radius, double width) {
	wheelBody->ChangeCollisionModel(new collision::ChCollisionModelParallel);

	ChCollisionModelParallel* coll_model = (ChCollisionModelParallel*)wheelBody->GetCollisionModel();
	coll_model->ClearModel();

	// Assemble the tire contact from 15 segments, properly offset.
	// Each segment is further decomposed in convex hulls.
	for (int iseg = 0; iseg < 15; iseg++) {
		ChQuaternion<> rot = Q_from_AngAxis(iseg * 24 * CH_C_DEG_TO_RAD, VECT_Y);
		for (int ihull = 0; ihull < num_hulls; ihull++) {
			std::vector<ChVector<> > convexhull;
			lugged_convex.GetConvexHullResult(ihull, convexhull);
			coll_model->AddConvexHull(convexhull, VNULL, rot);
		}
	}

	// Add a cylinder to represent the wheel hub.
	coll_model->AddCylinder(0.223, 0.223, 0.126);

	coll_model->BuildModel();

	wheelBody->GetMaterialSurface()->SetFriction(mu_t);
}

// Callback class for specifying chassis contact model.
// This version uses a box representing the chassis.
// In addition, this version overrides the visualization assets of the provided
// chassis body with the collision meshes.
void MyChassisBoxModel_vis::onCallback(ChSharedPtr<ChBodyAuxRef> chassisBody) {
  // Clear any existing assets (will be overriden)

  chassisBody->ChangeCollisionModel(new collision::ChCollisionModelParallel);

  chassisBody->GetCollisionModel()->ClearModel();
  ChVector<> chLoc = ChVector<>(0, 0, 0);
  //    ChVector<> chLoc = chassisBody->GetFrame_REF_to_COG().GetPos();
  chassisBody->GetCollisionModel()->AddBox(size.x, size.y, size.z, chLoc, rot);
  //    utils::AddBoxGeometry(
  //        chassisBody.get_ptr(), ChVector<>(1, .5, .05), ChVector<>(0, 0, 0), ChQuaternion<>(1, 0, 0, 0), true);
  chassisBody->GetCollisionModel()->SetFamily(chassisFam);
  chassisBody->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(tireFam);
  chassisBody->GetCollisionModel()->BuildModel();
  chassisBody->GetMaterialSurface()->SetFriction(mu_t);

  chassisBody->GetAssets().clear();
  ChSharedPtr<ChBoxShape> box(new ChBoxShape);
  box->GetBoxGeometry().Size = size;
  box->Rot = rot;
  chassisBody->GetAssets().push_back(box);
}

void MyChassisBoxModel_vis::SetAttributes(const ChVector<>& otherSize,
                           const ChQuaternion<>& otherRot,
                           const ChVector<>& otherLoc) {
  size = otherSize;
  rot = otherRot;
  loc = otherLoc;
}

// Callback class for specifying chassis contact model.
// This version uses a sphere representing the chassis.
// In addition, this version overrides the visualization assets of the provided
// chassis body with the collision meshes.
void MyChassisSphereModel_vis::onCallback(ChSharedPtr<ChBodyAuxRef> chassisBody) {
  // Clear any existing assets (will be overriden)

	chassisBody->ChangeCollisionModel(new collision::ChCollisionModelParallel);

  chassisBody->GetCollisionModel()->ClearModel();
  ChVector<> chLoc = ChVector<>(0, 0, 0);
//        ChVector<> chLoc = chassisBody->GetFrame_REF_to_COG().GetPos();
  chassisBody->GetCollisionModel()->AddSphere(rad, chLoc);
  //    utils::AddBoxGeometry(
  //        chassisBody.get_ptr(), ChVector<>(1, .5, .05), ChVector<>(0, 0, 0), ChQuaternion<>(1, 0, 0, 0), true);
  chassisBody->GetCollisionModel()->SetFamily(chassisFam);
  chassisBody->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(tireFam);
  chassisBody->GetCollisionModel()->BuildModel();
  chassisBody->GetMaterialSurface()->SetFriction(mu_t);

  chassisBody->GetAssets().clear();
  ChSharedPtr<ChSphereShape> sphere(new ChSphereShape);
  sphere->GetSphereGeometry().rad = rad;
  chassisBody->GetAssets().push_back(sphere);
}

void MyChassisSphereModel_vis::SetAttributes(double otherRad,
                           const ChQuaternion<>& otherRot,
                           const ChVector<>& otherLoc) {
  rad = otherRad;
  rot = otherRot;
  loc = otherLoc;
}

// Callback class for specifying chassis contact model.
// This version uses a convex decomposition of an obj representing the chassis.
MyChassisSimpleConvexMesh::MyChassisSimpleConvexMesh() :
	pos(chrono::ChVector<>(0, 0, 0)) , rot( chrono::ChQuaternion<>(1, 0, 0, 0)) {
  //    std::string chassis_obj_file("hmmwv/lugged_wheel_section.obj");
  //    std::string chassis_obj_file("hmmwv/lugged_wheel.obj");
  //    std::string chassis_obj_file("hmmwv/myHumvee.obj");
//  chassis_obj_file = std::string("hmmwv/myHumvee1.obj");
	chassis_obj_file = std::string("hmmwv/hmmwv_chassis_simple.obj");

  utils::LoadConvexMesh(vehicle::GetDataFile(chassis_obj_file), chassis_mesh, chassis_convex);
}

void MyChassisSimpleConvexMesh::onCallback(ChSharedPtr<ChBodyAuxRef> chassisBody) {
	chassisBody->ChangeCollisionModel(new collision::ChCollisionModelParallel);

  ChVector<> chLoc = ChVector<>(0, 0, 0);  // chassisBody->GetFrame_REF_to_COG().GetPos();
  chassisBody->GetCollisionModel()->ClearModel();
  //    utils::AddConvexCollisionModel(chassisBody, chassis_mesh, chassis_convex, chLoc, ChQuaternion<>(1, 0, 0, 0),
  //    false);

  // **************************
  ChSharedPtr<ChBody> body = chassisBody;
  geometry::ChTriangleMeshConnected& convex_mesh = chassis_mesh;
  ChConvexDecompositionHACDv2& convex_shape = chassis_convex;
  ChConvexDecomposition* used_decomposition = &convex_shape;

  //*****
  int hull_count = used_decomposition->GetHullCount();

  for (int c = 0; c < hull_count; c++) {
    std::vector<ChVector<double> > convexhull;
    used_decomposition->GetConvexHullResult(c, convexhull);

    ((collision::ChCollisionModelParallel*)body->GetCollisionModel())->AddConvexHull(convexhull, chLoc, rot);
  }
  chassisBody->GetCollisionModel()->SetFamily(chassisFam);
//    printf("chassis family %d \n", chassisBody->GetCollisionModel()->GetFamily());
  chassisBody->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(tireFam);
  chassisBody->GetCollisionModel()->BuildModel();

  // **************************

  //        chassisBody->RecomputeCollisionModel();
  //        chassisBody->SetCollide(false);

  chassisBody->GetMaterialSurface()->SetFriction(mu_t);
}

// Callback class for specifying chassis contact model.
// This version uses a triangular given in an obj representing the chassis.
// In addition, this version overrides the visualization assets of the provided
// chassis body with the collision meshes.
MyChassisSimpleTriMesh_vis::MyChassisSimpleTriMesh_vis() :
	pos(chrono::ChVector<>(0, 0, 0)) , rot( chrono::ChQuaternion<>(1, 0, 0, 0)) {
//	chassis_obj_file = std::string("hmmwv/myHumvee1.obj");
	chassis_obj_file = std::string("hmmwv/hmmwv_chassis_simple.obj");
}

void MyChassisSimpleTriMesh_vis::onCallback(ChSharedPtr<ChBodyAuxRef> chassisBody) {
	chassisBody->ChangeCollisionModel(new collision::ChCollisionModelParallel);

  // Clear any existing assets (will be overriden)
  const std::string mesh_name("chassis");

  chassisBody->GetAssets().clear();
  //    ChVector<> chLoc = ChVector<>(0,0,0);//chassisBody->GetFrame_REF_to_COG().GetPos();

  chassisBody->GetCollisionModel()->ClearModel();
  //    utils::AddTriangleMeshGeometry(chassisBody.get_ptr(), vehicle::GetDataFile(chassis_obj_file), mesh_name, pos,
  //    rot, true);

      ChVector<> chLoc = ChVector<>(0, 0, 0);  // chassisBody->GetFrame_REF_to_COG().GetPos();
//    ChVector<> chLoc = chassisBody->GetFrame_REF_to_COG().GetPos();

  // *** here
  std::string obj_filename = vehicle::GetDataFile(chassis_obj_file);
  const std::string& name = mesh_name;
  ChBody* body = chassisBody.get_ptr();
  geometry::ChTriangleMeshConnected trimesh;
  trimesh.LoadWavefrontMesh(obj_filename, false, false);

  for (int i = 0; i < trimesh.m_vertices.size(); i++)
    trimesh.m_vertices[i] = pos + rot.Rotate(trimesh.m_vertices[i]);

  body->GetCollisionModel()->AddTriangleMesh(trimesh, false, false, chLoc);

  if (true) {
    ChSharedPtr<ChTriangleMeshShape> trimesh_shape(new ChTriangleMeshShape);
    trimesh_shape->SetMesh(trimesh);
    trimesh_shape->SetName(name);
    trimesh_shape->Pos = ChVector<>(0, 0, 0);
    trimesh_shape->Rot = ChQuaternion<>(1, 0, 0, 0);
    body->GetAssets().push_back(trimesh_shape);
  }
  // *** to here
  chassisBody->GetCollisionModel()->SetFamily(chassisFam);
  chassisBody->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(tireFam);
  chassisBody->GetCollisionModel()->BuildModel();

  chassisBody->GetMaterialSurface()->SetFriction(mu_t);
}

<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems                */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

#include "VirtualMachineTemplate.h"

using namespace std;

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

std::map<std::string, std::set<std::string> > VirtualMachineTemplate::restricted;
std::map<std::string, std::set<std::string> > VirtualMachineTemplate::encrypted;

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualMachineTemplate::replace_disk_image(int target_id, const string&
    target_name, const string& target_uname, const string& new_name,
    const string& new_uname)
{
    int num_disks;
    int tmp_id;

    string tmp_name;
    string tmp_uname;

    vector<VectorAttribute  *> disks;
    VectorAttribute *    disk = 0;

    num_disks = get("DISK", disks);

    for(int i=0; i<num_disks; i++)
    {
        disk = disks[i];

        if (disk->vector_value("IMAGE_ID", tmp_id) == 0) //DISK has IMAGE_ID
        {
            if (tmp_id == target_id)
            {
                break;
            }
        }
        else //IMAGE and IMAGE_UNAME
        {
            tmp_name  = disk->vector_value("IMAGE");
            tmp_uname = disk->vector_value("IMAGE_UNAME");

            bool uname = tmp_uname.empty() || tmp_uname == target_uname;

            if ( tmp_name == target_name && uname )
            {
                break;
            }
        }

        disk = 0;
    }

    if ( disk == 0 )
    {
        return -1;
    }

    disk->remove("IMAGE_ID");

    disk->replace("IMAGE", new_name);

    disk->replace("IMAGE_UNAME", new_uname);

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& VirtualMachineTemplate::to_xml_short(string& xml) const
{
    ostringstream oss;
    string labels;

    string schd_rank, schd_ds_rank;
    string schd_req, schd_ds_req;

    string user_prio;

    vector<const VectorAttribute*> attrs;

    if (attributes.empty())
    {
        oss << "<USER_TEMPLATE/>";
    }
    else
    {
         oss << "<USER_TEMPLATE>";

        /* ------------------------------------------------------------------ */
        /* Attributes required by Sunstone                                    */
        /*  - LABELS                                                          */
        /* ------------------------------------------------------------------ */
        if (get("LABELS", labels))
        {
            oss << "<LABELS>" << one_util::escape_xml(labels) << "</LABELS>";
        }

        /* ------------------------------------------------------------------ */
        /* Attributes required by Scheduler                                   */
        /*  - SCHED_RANK (RANK - deprecated)                                  */
        /*  - SCHED_DS_RANK                                                   */
        /*  - SCHED_REQUIREMENTS                                              */
        /*  - SCHED_DS_REQUIREMENTS                                           */
        /*                                                                    */
        /*  - SCHED_ACTION                                                    */
        /*  - PUBLIC_CLOUD                                                    */
        /* ------------------------------------------------------------------ */
        if (get("SCHED_RANK", schd_rank))
        {
            oss << "<SCHED_RANK>" << one_util::escape_xml(schd_rank)
                << "</SCHED_RANK>";
        }

        if (get("SCHED_DS_RANK", schd_ds_rank))
        {
            oss << "<SCHED_DS_RANK>" << one_util::escape_xml(schd_ds_rank)
                << "</SCHED_DS_RANK>";
        }

        if (get("SCHED_REQUIREMENTS", schd_req))
        {
            oss << "<SCHED_REQUIREMENTS>" << one_util::escape_xml(schd_req)
                << "</SCHED_REQUIREMENTS>";
        }

        if (get("SCHED_DS_REQUIREMENTS", schd_ds_req))
        {
            oss << "<SCHED_DS_REQUIREMENTS>" << one_util::escape_xml(schd_ds_req)
                << "</SCHED_DS_REQUIREMENTS>";
        }

        if (get("USER_PRIORITY", user_prio))
        {
            oss << "<USER_PRIORITY>" << one_util::escape_xml(user_prio)
                << "</USER_PRIORITY>";
        }

        if ( get("PUBLIC_CLOUD", attrs) > 0 )
        {
            for (auto vattr : attrs)
            {
                vattr->to_xml(oss);
            }
        }

        attrs.clear();

        if ( get("SCHED_ACTION", attrs) > 0 )
        {
            for (auto vattr : attrs)
            {
                vattr->to_xml(oss);
            }
        }

        oss << "</USER_TEMPLATE>";
    }

    xml = oss.str();

    return xml;
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

std::map<std::string,std::vector<std::string>> VirtualMachineTemplate::UPDATECONF_ATTRS = {
    { "OS",
        { "ARCH",
          "MACHINE",
          "KERNEL",
          "INITRD",
          "BOOTLOADER",
          "BOOT",
          "KERNEL_CMD",
          "ROOT",
          "SD_DISK_BUS",
          "UUID"}
    },
    { "FEATURES",
        { "PAE",
          "ACPI",
          "APIC",
          "LOCALTIME",
          "HYPERV",
          "GUEST_AGENT",
          "VIRTIO_SCSI_QUEUES",
          "IOTHREADS"}
    },
    { "INPUT",
        { "TYPE",
          "BUS"}
    },
    {"GRAPHICS",
        { "TYPE",
          "LISTEN",
          "PASSWD",
          "KEYMAP",
          "COMMAND"}
    },
    {"RAW",
        { "TYPE",
          "DATA",
          "DATA_VMX"}
    },
    {"CPU_MODEL",
        { "MODEL" }
    }
};

// -----------------------------------------------------------------------------
/**
 * returns a copy the values of a vector value
 */
static void copy_vector_values(const Template *old_tmpl, Template *new_tmpl,
        const char * name)
{
    string value;

    const VectorAttribute * old_attr = old_tmpl->get(name);

    if ( old_attr == 0 )
    {
        return;
    }

    VectorAttribute * new_vattr = new VectorAttribute(name);

    std::vector<std::string> vnames = VirtualMachineTemplate::UPDATECONF_ATTRS[name];

    for (const auto& vname : vnames)
    {
        std::string vval = old_attr->vector_value(vname);

        if (!vval.empty())
        {
            new_vattr->replace(vname, vval);
        }
    }

    if ( new_vattr->empty() )
    {
        delete new_vattr;
    }
    else
    {
        new_tmpl->set(new_vattr);
    }
}

// -----------------------------------------------------------------------------

unique_ptr<VirtualMachineTemplate> VirtualMachineTemplate::get_updateconf_template() const
{
    auto conf_tmpl = make_unique<VirtualMachineTemplate>();

    copy_vector_values(this, conf_tmpl.get(), "OS");

    copy_vector_values(this, conf_tmpl.get(), "FEATURES");

    copy_vector_values(this, conf_tmpl.get(), "INPUT");

    copy_vector_values(this, conf_tmpl.get(), "GRAPHICS");

    copy_vector_values(this, conf_tmpl.get(), "RAW");

    const VectorAttribute * context = get("CONTEXT");

    if ( context != 0 )
    {
        conf_tmpl->set(context->clone());
    }

    return conf_tmpl;
}

<commit_msg>B #5096: fix minor bug with CPU_MODEL (#979)<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems                */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

#include "VirtualMachineTemplate.h"

using namespace std;

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

std::map<std::string, std::set<std::string> > VirtualMachineTemplate::restricted;
std::map<std::string, std::set<std::string> > VirtualMachineTemplate::encrypted;

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualMachineTemplate::replace_disk_image(int target_id, const string&
    target_name, const string& target_uname, const string& new_name,
    const string& new_uname)
{
    int num_disks;
    int tmp_id;

    string tmp_name;
    string tmp_uname;

    vector<VectorAttribute  *> disks;
    VectorAttribute *    disk = 0;

    num_disks = get("DISK", disks);

    for(int i=0; i<num_disks; i++)
    {
        disk = disks[i];

        if (disk->vector_value("IMAGE_ID", tmp_id) == 0) //DISK has IMAGE_ID
        {
            if (tmp_id == target_id)
            {
                break;
            }
        }
        else //IMAGE and IMAGE_UNAME
        {
            tmp_name  = disk->vector_value("IMAGE");
            tmp_uname = disk->vector_value("IMAGE_UNAME");

            bool uname = tmp_uname.empty() || tmp_uname == target_uname;

            if ( tmp_name == target_name && uname )
            {
                break;
            }
        }

        disk = 0;
    }

    if ( disk == 0 )
    {
        return -1;
    }

    disk->remove("IMAGE_ID");

    disk->replace("IMAGE", new_name);

    disk->replace("IMAGE_UNAME", new_uname);

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& VirtualMachineTemplate::to_xml_short(string& xml) const
{
    ostringstream oss;
    string labels;

    string schd_rank, schd_ds_rank;
    string schd_req, schd_ds_req;

    string user_prio;

    vector<const VectorAttribute*> attrs;

    if (attributes.empty())
    {
        oss << "<USER_TEMPLATE/>";
    }
    else
    {
         oss << "<USER_TEMPLATE>";

        /* ------------------------------------------------------------------ */
        /* Attributes required by Sunstone                                    */
        /*  - LABELS                                                          */
        /* ------------------------------------------------------------------ */
        if (get("LABELS", labels))
        {
            oss << "<LABELS>" << one_util::escape_xml(labels) << "</LABELS>";
        }

        /* ------------------------------------------------------------------ */
        /* Attributes required by Scheduler                                   */
        /*  - SCHED_RANK (RANK - deprecated)                                  */
        /*  - SCHED_DS_RANK                                                   */
        /*  - SCHED_REQUIREMENTS                                              */
        /*  - SCHED_DS_REQUIREMENTS                                           */
        /*                                                                    */
        /*  - SCHED_ACTION                                                    */
        /*  - PUBLIC_CLOUD                                                    */
        /* ------------------------------------------------------------------ */
        if (get("SCHED_RANK", schd_rank))
        {
            oss << "<SCHED_RANK>" << one_util::escape_xml(schd_rank)
                << "</SCHED_RANK>";
        }

        if (get("SCHED_DS_RANK", schd_ds_rank))
        {
            oss << "<SCHED_DS_RANK>" << one_util::escape_xml(schd_ds_rank)
                << "</SCHED_DS_RANK>";
        }

        if (get("SCHED_REQUIREMENTS", schd_req))
        {
            oss << "<SCHED_REQUIREMENTS>" << one_util::escape_xml(schd_req)
                << "</SCHED_REQUIREMENTS>";
        }

        if (get("SCHED_DS_REQUIREMENTS", schd_ds_req))
        {
            oss << "<SCHED_DS_REQUIREMENTS>" << one_util::escape_xml(schd_ds_req)
                << "</SCHED_DS_REQUIREMENTS>";
        }

        if (get("USER_PRIORITY", user_prio))
        {
            oss << "<USER_PRIORITY>" << one_util::escape_xml(user_prio)
                << "</USER_PRIORITY>";
        }

        if ( get("PUBLIC_CLOUD", attrs) > 0 )
        {
            for (auto vattr : attrs)
            {
                vattr->to_xml(oss);
            }
        }

        attrs.clear();

        if ( get("SCHED_ACTION", attrs) > 0 )
        {
            for (auto vattr : attrs)
            {
                vattr->to_xml(oss);
            }
        }

        oss << "</USER_TEMPLATE>";
    }

    xml = oss.str();

    return xml;
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

std::map<std::string,std::vector<std::string>> VirtualMachineTemplate::UPDATECONF_ATTRS = {
    { "OS",
        { "ARCH",
          "MACHINE",
          "KERNEL",
          "INITRD",
          "BOOTLOADER",
          "BOOT",
          "KERNEL_CMD",
          "ROOT",
          "SD_DISK_BUS",
          "UUID"}
    },
    { "FEATURES",
        { "PAE",
          "ACPI",
          "APIC",
          "LOCALTIME",
          "HYPERV",
          "GUEST_AGENT",
          "VIRTIO_SCSI_QUEUES",
          "IOTHREADS"}
    },
    { "INPUT",
        { "TYPE",
          "BUS"}
    },
    {"GRAPHICS",
        { "TYPE",
          "LISTEN",
          "PASSWD",
          "KEYMAP",
          "COMMAND"}
    },
    {"RAW",
        { "TYPE",
          "DATA",
          "DATA_VMX"}
    },
    {"CPU_MODEL",
        { "MODEL" }
    }
};

// -----------------------------------------------------------------------------
/**
 * returns a copy the values of a vector value
 */
static void copy_vector_values(const Template *old_tmpl, Template *new_tmpl,
        const char * name)
{
    string value;

    const VectorAttribute * old_attr = old_tmpl->get(name);

    if ( old_attr == 0 )
    {
        return;
    }

    VectorAttribute * new_vattr = new VectorAttribute(name);

    std::vector<std::string> vnames = VirtualMachineTemplate::UPDATECONF_ATTRS[name];

    for (const auto& vname : vnames)
    {
        std::string vval = old_attr->vector_value(vname);

        if (!vval.empty())
        {
            new_vattr->replace(vname, vval);
        }
    }

    if ( new_vattr->empty() )
    {
        delete new_vattr;
    }
    else
    {
        new_tmpl->set(new_vattr);
    }
}

// -----------------------------------------------------------------------------

unique_ptr<VirtualMachineTemplate> VirtualMachineTemplate::get_updateconf_template() const
{
    auto conf_tmpl = make_unique<VirtualMachineTemplate>();

    copy_vector_values(this, conf_tmpl.get(), "OS");

    copy_vector_values(this, conf_tmpl.get(), "FEATURES");

    copy_vector_values(this, conf_tmpl.get(), "INPUT");

    copy_vector_values(this, conf_tmpl.get(), "GRAPHICS");

    copy_vector_values(this, conf_tmpl.get(), "RAW");

    copy_vector_values(this, conf_tmpl.get(), "CPU_MODEL");

    const VectorAttribute * context = get("CONTEXT");

    if ( context != 0 )
    {
        conf_tmpl->set(context->clone());
    }

    return conf_tmpl;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: estack.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: np $ $Date: 2002-03-08 14:45:27 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef ARY_ESTACK_HXX
#define ARY_ESTACK_HXX

// USED SERVICES
    // BASE CLASSES
#include <slist>
    // COMPONENTS
    // PARAMETERS

template <class ELEM>
class EStack : private std::slist<ELEM>
{
  private:
    typedef std::slist<ELEM>    base;
    const base &        Base() const            { return *this; }
    base &              Base()                  { return *this; }

  public:
    typedef ELEM                                value_type;
    typedef std::slist<ELEM>::size_type         size_type;

    // LIFECYCLE
                        EStack()                {}
                        EStack(
                            const EStack &      i_rStack )
                                                :   base( (const base &)(i_rStack) ) {}
                        ~EStack()               {}
    // OPERATORS
    EStack &            operator=(
                            const EStack &      i_rStack )
                                                { base::operator=( i_rStack.Base() );
                                                  return *this; }
    bool                operator==(
                            const EStack<ELEM> &
                                                i_r2 ) const
                                                { return std::operator==( Base(), i_rStack.Base() ); }
    bool                operator<(
                            const EStack<ELEM> &
                                                i_r2 ) const
                                                { return std::operator<( Base(), i_rStack.Base() ); }
    // OPERATIONS
    void                push(
                            const value_type &  i_rElem )
                                                { base::push_front(i_rElem); }
    void                pop()                   { base::pop_front(); }
    void                erase_all()             { while (NOT empty()) pop(); }

    // INQUIRY
    const value_type &  top() const             { return base::front(); }
    size_type           size() const            { return base::size(); }
    bool                empty() const           { return base::empty(); }

    // ACCESS
    value_type &        top()                   { return base::front(); }
};

// IMPLEMENTATION

#endif

<commit_msg>INTEGRATION: CWS adc6 (1.1.1.1.50); FILE MERGED 2003/06/26 14:43:32 np 1.1.1.1.50.1: #110259# Fix differing output on Windows vs. Unix and remove broken links from output.<commit_after>/*************************************************************************
 *
 *  $RCSfile: estack.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2003-06-30 15:27:34 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef ARY_ESTACK_HXX
#define ARY_ESTACK_HXX

// USED SERVICES
    // BASE CLASSES
#include <slist>
    // COMPONENTS
    // PARAMETERS

template <class ELEM>
class EStack : private std::slist<ELEM>
{
  private:
    typedef std::slist<ELEM>    base;
    const base &        Base() const            { return *this; }
    base &              Base()                  { return *this; }

  public:
    typedef ELEM                                    value_type;
    typedef typename std::slist<ELEM>::size_type    size_type;

    // LIFECYCLE
                        EStack()                {}
                        EStack(
                            const EStack &      i_rStack )
                                                :   base( (const base &)(i_rStack) ) {}
                        ~EStack()               {}
    // OPERATORS
    EStack &            operator=(
                            const EStack &      i_rStack )
                                                { base::operator=( i_rStack.Base() );
                                                  return *this; }
    bool                operator==(
                            const EStack<ELEM> &
                                                i_r2 ) const
                                                { return std::operator==( Base(), i_rStack.Base() ); }
    bool                operator<(
                            const EStack<ELEM> &
                                                i_r2 ) const
                                                { return std::operator<( Base(), i_rStack.Base() ); }
    // OPERATIONS
    void                push(
                            const value_type &  i_rElem )
                                                { base::push_front(i_rElem); }
    void                pop()                   { base::pop_front(); }
    void                erase_all()             { while (NOT empty()) pop(); }

    // INQUIRY
    const value_type &  top() const             { return base::front(); }
    size_type           size() const            { return base::size(); }
    bool                empty() const           { return base::empty(); }

    // ACCESS
    value_type &        top()                   { return base::front(); }
};

// IMPLEMENTATION

#endif

<|endoftext|>


<commit_before><commit_msg>Added unit test relative displacement<commit_after><|endoftext|>