<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Aristid Breitkreuz, Ruediger Sonderfeld

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 "flusspferd/context.hpp"
#include "flusspferd/object.hpp"
#include "flusspferd/exception.hpp"
#include "flusspferd/local_root_scope.hpp"
#include "flusspferd/spidermonkey/context.hpp"
#include "flusspferd/spidermonkey/value.hpp"
#include "flusspferd/spidermonkey/object.hpp"
#include "flusspferd/spidermonkey/runtime.hpp"
#include "flusspferd/current_context_scope.hpp"
#include <boost/unordered_map.hpp>
#include <cstring>
#include <cstdio>
#include <js/jsapi.h>

#ifndef FLUSSPFERD_STACKCHUNKSIZE
#define FLUSSPFERD_STACKCHUNKSIZE 8192
#endif

using namespace flusspferd;

namespace {
  static JSClass global_class = {
    "global", JSCLASS_GLOBAL_FLAGS,
    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
    JSCLASS_NO_OPTIONAL_MEMBERS
  };
}

struct context::context_private {
  typedef boost::shared_ptr<root_object> root_object_ptr;
  boost::unordered_map<std::string, root_object_ptr> prototypes;
  boost::unordered_map<std::string, root_object_ptr> constructors;
};

class context::impl {
public:
  impl()
    : context(JS_NewContext(Impl::get_runtime(),
                            FLUSSPFERD_STACKCHUNKSIZE)),
      destroy(true)
  {
    if(!context)
      throw exception("Could not create Spidermonkey Context");

    uint32 options = JS_GetOptions(context);

    options |= JSOPTION_VAROBJFIX;
    options |= JSOPTION_DONT_REPORT_UNCAUGHT;
    options &= ~JSOPTION_XML;

    JS_SetVersion(context, JSVersion(JS_VERSION));
    JS_SetOptions(context, options);

    JS_BeginRequest(context);

    JSObject *global_ = JS_NewObject(context, &global_class, 0x0, 0x0);
    if(!global_)
      throw exception("Could not create Global Object");

    JS_SetGlobalObject(context, global_);

    if(!JS_InitStandardClasses(context, global_))
      throw exception("Could not initialize Global Object");

    JS_DeleteProperty(context, global_, "XML");

    JS_SetContextPrivate(context, static_cast<void*>(new context_private));
  }

  explicit impl(JSContext *context)
    : context(context), destroy(false)
  { }

  ~impl() {
    if (destroy) {
      {
        current_context_scope scope(Impl::wrap_context(context));
        delete get_private();
        JS_DestroyContext(context);
      }
    }
  }

  bool is_valid() {
    return context;
  }

  context_private *get_private() {
    return static_cast<context_private*>(JS_GetContextPrivate(context));
  }

  JSContext *context;
  bool destroy;
};

struct context::detail {
  JSContext *c;
  detail(JSContext *ct) : c(ct) { }

  static JSContext *get(context &co) {
    return co.p->context;
  }
};

JSContext *Impl::get_context(context &co) {
  return context::detail::get(co);
}

context Impl::wrap_context(JSContext *c) {
  return context(c);
}

context::context()
{ }
context::context(context::detail const &d)
  : p(new impl(d.c))
{
  if (!p->is_valid())
    p.reset();
}
context::~context() { }

context context::create() {
  context c;
  c.p.reset(new impl);
  return c;
}

bool context::is_valid() const {
  return p;
}

object context::global() {
  return Impl::wrap_object(JS_GetGlobalObject(p->context));
}

object context::scope_chain() {
  return Impl::wrap_object(JS_GetScopeChain(p->context));
}

void context::add_prototype(std::string const &name, object const &proto) {
  p->get_private()->prototypes[name] =
    context_private::root_object_ptr(new root_object(proto));
}

object context::prototype(std::string const &name) const {
  context_private::root_object_ptr ptr = p->get_private()->prototypes[name];
  return ptr ? *ptr : object();
}

void context::add_constructor(std::string const &name, object const &ctor) {
  p->get_private()->constructors[name] =
    context_private::root_object_ptr(new root_object(ctor));
}

object context::constructor(std::string const &name) const {
  context_private::root_object_ptr ptr = p->get_private()->constructors[name];
  return ptr ? *ptr : object();
}

void context::gc() {
  JS_GC(p->context);
}
<commit_msg>fix bug where flusspferd did not compile if JS_THREADSAFE was not enabled in spidermonkey<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Aristid Breitkreuz, Ruediger Sonderfeld

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 "flusspferd/context.hpp"
#include "flusspferd/object.hpp"
#include "flusspferd/exception.hpp"
#include "flusspferd/local_root_scope.hpp"
#include "flusspferd/spidermonkey/context.hpp"
#include "flusspferd/spidermonkey/value.hpp"
#include "flusspferd/spidermonkey/object.hpp"
#include "flusspferd/spidermonkey/runtime.hpp"
#include "flusspferd/current_context_scope.hpp"
#include <boost/unordered_map.hpp>
#include <cstring>
#include <cstdio>
#include <js/jsapi.h>

#ifndef FLUSSPFERD_STACKCHUNKSIZE
#define FLUSSPFERD_STACKCHUNKSIZE 8192
#endif

using namespace flusspferd;

namespace {
  static JSClass global_class = {
    "global", JSCLASS_GLOBAL_FLAGS,
    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
    JSCLASS_NO_OPTIONAL_MEMBERS
  };
}

struct context::context_private {
  typedef boost::shared_ptr<root_object> root_object_ptr;
  boost::unordered_map<std::string, root_object_ptr> prototypes;
  boost::unordered_map<std::string, root_object_ptr> constructors;
};

class context::impl {
public:
  impl()
    : context(JS_NewContext(Impl::get_runtime(),
                            FLUSSPFERD_STACKCHUNKSIZE)),
      destroy(true)
  {
    if(!context)
      throw exception("Could not create Spidermonkey Context");

    uint32 options = JS_GetOptions(context);

    options |= JSOPTION_VAROBJFIX;
    options |= JSOPTION_DONT_REPORT_UNCAUGHT;
    options &= ~JSOPTION_XML;

    JS_SetVersion(context, JSVersion(JS_VERSION));
    JS_SetOptions(context, options);

#ifdef JS_THREADSAFE
    JS_BeginRequest(context);
#endif

    JSObject *global_ = JS_NewObject(context, &global_class, 0x0, 0x0);
    if(!global_)
      throw exception("Could not create Global Object");

    JS_SetGlobalObject(context, global_);

    if(!JS_InitStandardClasses(context, global_))
      throw exception("Could not initialize Global Object");

    JS_DeleteProperty(context, global_, "XML");

    JS_SetContextPrivate(context, static_cast<void*>(new context_private));
  }

  explicit impl(JSContext *context)
    : context(context), destroy(false)
  { }

  ~impl() {
    if (destroy) {
      {
        current_context_scope scope(Impl::wrap_context(context));
        delete get_private();
        JS_DestroyContext(context);
      }
    }
  }

  bool is_valid() {
    return context;
  }

  context_private *get_private() {
    return static_cast<context_private*>(JS_GetContextPrivate(context));
  }

  JSContext *context;
  bool destroy;
};

struct context::detail {
  JSContext *c;
  detail(JSContext *ct) : c(ct) { }

  static JSContext *get(context &co) {
    return co.p->context;
  }
};

JSContext *Impl::get_context(context &co) {
  return context::detail::get(co);
}

context Impl::wrap_context(JSContext *c) {
  return context(c);
}

context::context()
{ }
context::context(context::detail const &d)
  : p(new impl(d.c))
{
  if (!p->is_valid())
    p.reset();
}
context::~context() { }

context context::create() {
  context c;
  c.p.reset(new impl);
  return c;
}

bool context::is_valid() const {
  return p;
}

object context::global() {
  return Impl::wrap_object(JS_GetGlobalObject(p->context));
}

object context::scope_chain() {
  return Impl::wrap_object(JS_GetScopeChain(p->context));
}

void context::add_prototype(std::string const &name, object const &proto) {
  p->get_private()->prototypes[name] =
    context_private::root_object_ptr(new root_object(proto));
}

object context::prototype(std::string const &name) const {
  context_private::root_object_ptr ptr = p->get_private()->prototypes[name];
  return ptr ? *ptr : object();
}

void context::add_constructor(std::string const &name, object const &ctor) {
  p->get_private()->constructors[name] =
    context_private::root_object_ptr(new root_object(ctor));
}

object context::constructor(std::string const &name) const {
  context_private::root_object_ptr ptr = p->get_private()->constructors[name];
  return ptr ? *ptr : object();
}

void context::gc() {
  JS_GC(p->context);
}
<|endoftext|>


<commit_before>#include "ai.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace BWAPI;
using namespace Filter;

// Global variables.
bool infantryBuildingNeeded;
bool supplyNeeded;
bool supplyProviderTypeIsBuilding;
int infantryBuildingCheckTimer;
int savingMinerals;
int supplyCheckTimer;
Race playerRace;
static int infantryBuildingChecked;
static int supplyChecked;
UnitType infantryBuilding;
UnitType infantryType;
UnitType supplyProviderType;

void ai::onEnd(bool isWinner){
}

void ai::onFrame(){
    int frameCount = Broodwar->getFrameCount();

    if(!Broodwar->self()
      || frameCount % Broodwar->getLatencyFrames() != 0
      || Broodwar->isPaused()
      || Broodwar->isReplay()){
        return;
    }

    int minerals = Broodwar->self()->minerals();
    int supplyTotal = Broodwar->self()->supplyTotal();

    if(supplyTotal < 200
      && supplyTotal - Broodwar->self()->supplyUsed() <= 2){
        savingMinerals = 100;
        supplyNeeded = true;

    }else{
        savingMinerals = 0;
        supplyNeeded = false;
    }

    if(minerals > 200){
        infantryBuildingNeeded = true;
        savingMinerals = 200;
    }

    for(auto &unit : Broodwar->self()->getUnits()){
        if(!unit->exists()
          || !unit->isCompleted()
          || unit->isConstructing()
          || unit->isLoaded()
          || unit->isLockedDown()
          || unit->isMaelstrommed()
          || !unit->isPowered()
          || unit->isStasised()
          || unit->isStuck()){
            continue;
        }

        // Setup unit information variables.
        bool unitIsIdle = unit->isIdle();
        UnitType unitType = unit->getType();

        // Handle workers.
        if(unitType.isWorker()){
            // Handle insufficient supply by building Pylon, building Supply Depot, or training Overlord.
            if(supplyNeeded
              && minerals >= savingMinerals
              && supplyChecked + supplyCheckTimer < frameCount){
                supplyChecked = frameCount;

                if(Broodwar->self()->incompleteUnitCount(supplyProviderType) == 0){
                    Unit supplyBuilder = unit->getClosestUnit(GetType == supplyProviderType.whatBuilds().first
                      && (IsIdle || IsGatheringMinerals)
                      && IsOwned);

                    if(supplyProviderTypeIsBuilding){
                        buildBuilding(
                          supplyBuilder,
                          supplyProviderType
                        );

                    }else{
                        supplyBuilder->train(supplyProviderType);
                    }
                }

            // Build Barracks/Gateway/Spawning Pool.
            }else if(infantryBuildingNeeded
              && minerals >= savingMinerals
              && infantryBuildingChecked + infantryBuildingCheckTimer < frameCount){
                infantryBuildingChecked = frameCount;

                if(buildBuilding(
                  unit,
                  infantryBuilding
                )){
                    infantryBuildingNeeded = false;
                    savingMinerals = 0;
                }

            }else if(unitIsIdle){
                // Return resources.
                if(unit->isCarryingMinerals()
                  || unit->isCarryingGas()){
                    unit->returnCargo();

                // Gather resources.
                }else{
                    unit->gather(unit->getClosestUnit(IsMineralField || IsRefinery));
                }
            }

        }else if(unitIsIdle){
            // Handle Command Centers, Hatcheries, and Nexuses.
            if(unitType.isResourceDepot()){
                if(minerals >= savingMinerals + 50){
                    // Train workers.
                    unit->train(playerRace.getWorker());
                }

            // Handle Barracks and Gateways.
            }else if(unit->canTrain(infantryType)){
                if(minerals >= savingMinerals + 100){
                    // Train Marines and Zealots.
                    unit->train(infantryType);
                }

            // Everything else should attack-move scout.
            }else{
                Position position = unit->getPosition();
                position.x += rand() % 501 - 250;
                position.y += rand() % 501 - 250;
                unit->attack(position);
            }
        }
    }
}

void ai::onNukeDetect(BWAPI::Position target){
}

void ai::onPlayerLeft(BWAPI::Player player){
}

void ai::onReceiveText(BWAPI::Player player, std::string text){
}

void ai::onSaveGame(std::string gameName){
}

void ai::onSendText(std::string text){
    Broodwar->sendText("%s", text.c_str());
}

void ai::onStart(){
    Broodwar->setCommandOptimizationLevel(1);
    srand(time(NULL));

    // Setup global variables.
    infantryBuildingChecked = 0;
    infantryBuildingCheckTimer = 2000;
    infantryBuildingNeeded = false;
    playerRace = Broodwar->self()->getRace();
    savingMinerals = 0;
    supplyChecked = 0;
    supplyCheckTimer = 600;
    supplyNeeded = false;
    supplyProviderType = playerRace.getSupplyProvider();

    supplyProviderTypeIsBuilding = supplyProviderType.isBuilding();

    // Handle race-specific stuff.
    if(playerRace == Races::Zerg){
        infantryBuilding = UnitTypes::Zerg_Spawning_Pool;
        infantryType = UnitTypes::Zerg_Zergling;

    }else if(playerRace == Races::Terran){
        infantryBuilding = UnitTypes::Terran_Barracks;
        infantryType = UnitTypes::Terran_Marine;

    }else{
        infantryBuilding = UnitTypes::Protoss_Gateway;
        infantryType = UnitTypes::Protoss_Zealot;
    }

    Broodwar->sendText("glhf");
}

void ai::onUnitComplete(BWAPI::Unit unit){
}

void ai::onUnitCreate(BWAPI::Unit unit){
}

void ai::onUnitDestroy(BWAPI::Unit unit){
}

void ai::onUnitDiscover(BWAPI::Unit unit){
}

void ai::onUnitEvade(BWAPI::Unit unit){
}

void ai::onUnitHide(BWAPI::Unit unit){
}

void ai::onUnitMorph(BWAPI::Unit unit){
}

void ai::onUnitRenegade(BWAPI::Unit unit){
}

void ai::onUnitShow(BWAPI::Unit unit){
}

bool buildBuilding(Unit builder, UnitType building){
    TilePosition targetBuildLocation = Broodwar->getBuildLocation(
      builing,
      builder->getTilePosition()
    );

    if(targetBuildLocation){
        return builder->build(
          building,
          targetBuildLocation
        );
    }

    return false;
}

<commit_msg>moved incomplete supply provider check to supply needed check<commit_after>#include "ai.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace BWAPI;
using namespace Filter;

// Global variables.
bool infantryBuildingNeeded;
bool supplyNeeded;
bool supplyProviderTypeIsBuilding;
int infantryBuildingCheckTimer;
int savingMinerals;
int supplyCheckTimer;
Race playerRace;
static int infantryBuildingChecked;
static int supplyChecked;
UnitType infantryBuilding;
UnitType infantryType;
UnitType supplyProviderType;

void ai::onEnd(bool isWinner){
}

void ai::onFrame(){
    int frameCount = Broodwar->getFrameCount();

    if(!Broodwar->self()
      || frameCount % Broodwar->getLatencyFrames() != 0
      || Broodwar->isPaused()
      || Broodwar->isReplay()){
        return;
    }

    int minerals = Broodwar->self()->minerals();
    int supplyTotal = Broodwar->self()->supplyTotal();

    if(supplyTotal < 200
      && supplyTotal - Broodwar->self()->supplyUsed() <= 2
      && Broodwar->self()->incompleteUnitCount(supplyProviderType) == 0){
        savingMinerals = 100;
        supplyNeeded = true;

    }else{
        savingMinerals = 0;
        supplyNeeded = false;
    }

    if(minerals > 200){
        infantryBuildingNeeded = true;
        savingMinerals = 200;
    }

    for(auto &unit : Broodwar->self()->getUnits()){
        if(!unit->exists()
          || !unit->isCompleted()
          || unit->isConstructing()
          || unit->isLoaded()
          || unit->isLockedDown()
          || unit->isMaelstrommed()
          || !unit->isPowered()
          || unit->isStasised()
          || unit->isStuck()){
            continue;
        }

        // Setup unit information variables.
        bool unitIsIdle = unit->isIdle();
        UnitType unitType = unit->getType();

        // Handle workers.
        if(unitType.isWorker()){
            // Handle insufficient supply by building Pylon, building Supply Depot, or training Overlord.
            if(supplyNeeded
              && minerals >= savingMinerals
              && supplyChecked + supplyCheckTimer < frameCount){
                supplyChecked = frameCount;

                Unit supplyBuilder = unit->getClosestUnit(GetType == supplyProviderType.whatBuilds().first
                  && (IsIdle || IsGatheringMinerals)
                  && IsOwned);

                if(supplyProviderTypeIsBuilding){
                    buildBuilding(
                      supplyBuilder,
                      supplyProviderType
                    );

                }else{
                    supplyBuilder->train(supplyProviderType);
                }

            // Build Barracks/Gateway/Spawning Pool.
            }else if(infantryBuildingNeeded
              && minerals >= savingMinerals
              && infantryBuildingChecked + infantryBuildingCheckTimer < frameCount){
                infantryBuildingChecked = frameCount;

                if(buildBuilding(
                  unit,
                  infantryBuilding
                )){
                    infantryBuildingNeeded = false;
                    savingMinerals = 0;
                }

            }else if(unitIsIdle){
                // Return resources.
                if(unit->isCarryingMinerals()
                  || unit->isCarryingGas()){
                    unit->returnCargo();

                // Gather resources.
                }else{
                    unit->gather(unit->getClosestUnit(IsMineralField || IsRefinery));
                }
            }

        }else if(unitIsIdle){
            // Handle Command Centers, Hatcheries, and Nexuses.
            if(unitType.isResourceDepot()){
                if(minerals >= savingMinerals + 50){
                    // Train workers.
                    unit->train(playerRace.getWorker());
                }

            // Handle Barracks and Gateways.
            }else if(unit->canTrain(infantryType)){
                if(minerals >= savingMinerals + 100){
                    // Train Marines and Zealots.
                    unit->train(infantryType);
                }

            // Everything else should attack-move scout.
            }else{
                Position position = unit->getPosition();
                position.x += rand() % 501 - 250;
                position.y += rand() % 501 - 250;
                unit->attack(position);
            }
        }
    }
}

void ai::onNukeDetect(BWAPI::Position target){
}

void ai::onPlayerLeft(BWAPI::Player player){
}

void ai::onReceiveText(BWAPI::Player player, std::string text){
}

void ai::onSaveGame(std::string gameName){
}

void ai::onSendText(std::string text){
    Broodwar->sendText("%s", text.c_str());
}

void ai::onStart(){
    Broodwar->setCommandOptimizationLevel(1);
    srand(time(NULL));

    // Setup global variables.
    infantryBuildingChecked = 0;
    infantryBuildingCheckTimer = 2000;
    infantryBuildingNeeded = false;
    playerRace = Broodwar->self()->getRace();
    savingMinerals = 0;
    supplyChecked = 0;
    supplyCheckTimer = 600;
    supplyNeeded = false;
    supplyProviderType = playerRace.getSupplyProvider();

    supplyProviderTypeIsBuilding = supplyProviderType.isBuilding();

    // Handle race-specific stuff.
    if(playerRace == Races::Zerg){
        infantryBuilding = UnitTypes::Zerg_Spawning_Pool;
        infantryType = UnitTypes::Zerg_Zergling;

    }else if(playerRace == Races::Terran){
        infantryBuilding = UnitTypes::Terran_Barracks;
        infantryType = UnitTypes::Terran_Marine;

    }else{
        infantryBuilding = UnitTypes::Protoss_Gateway;
        infantryType = UnitTypes::Protoss_Zealot;
    }

    Broodwar->sendText("glhf");
}

void ai::onUnitComplete(BWAPI::Unit unit){
}

void ai::onUnitCreate(BWAPI::Unit unit){
}

void ai::onUnitDestroy(BWAPI::Unit unit){
}

void ai::onUnitDiscover(BWAPI::Unit unit){
}

void ai::onUnitEvade(BWAPI::Unit unit){
}

void ai::onUnitHide(BWAPI::Unit unit){
}

void ai::onUnitMorph(BWAPI::Unit unit){
}

void ai::onUnitRenegade(BWAPI::Unit unit){
}

void ai::onUnitShow(BWAPI::Unit unit){
}

bool buildBuilding(Unit builder, UnitType building){
    TilePosition targetBuildLocation = Broodwar->getBuildLocation(
      builing,
      builder->getTilePosition()
    );

    if(targetBuildLocation){
        return builder->build(
          building,
          targetBuildLocation
        );
    }

    return false;
}

<|endoftext|>


<commit_before>/** @file
    @brief Implementation

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2016 Sensics, Inc.
//
// 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.

// Internal Includes
#include "ConfigParams.h"
#include "IMUStateMeasurements.h"

// Library/third-party includes
#include <osvr/Util/Angles.h>

// Standard includes
#include <iostream>
#include <memory>

#define CATCH_CONFIG_MAIN
#include "catch_typelist.h"
#include <catch.hpp>

using std::unique_ptr;
using namespace osvr;
using namespace vbtracker;
using namespace Eigen;
struct TestData {
    TestData() {
        /// Set up from a default configuration.
        ConfigParams params;
#if 0
        state.setErrorCovariance(
            kalman::types::DimVector<BodyState>::Constant(100).asDiagonal());
#endif

        /// configure the process model
        processModel.setDamping(params.linearVelocityDecayCoefficient,
                                params.angularVelocityDecayCoefficient);
        processModel.setNoiseAutocorrelation(
            kalman::types::Vector<6>::Map(params.processNoiseAutocorrelation));

        /// Save the IMU measurement parameters.
        imuVariance = Eigen::Vector3d::Constant(params.imu.orientationVariance);
    }
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
    /// Quantity computed from the "camera pose" (room calibration output)
    Eigen::Quaterniond roomToCameraRotation = Eigen::Quaterniond::Identity();

    /// Quantity computed during room calibration output
    util::Angle yawCorrection = 0;

    /// Transform the IMU-measured quaternion using the calibration output
    /// mocked up in this struct.
    Eigen::Quaterniond xform(Eigen::Quaterniond const &quat) {
        return getTransformedOrientation(quat, roomToCameraRotation,
                                         yawCorrection);
    }

    /// Default constructor is no translation, identity rotation, 10 along
    /// main diagonal as the state covariance matrix.
    BodyState state;

    BodyProcessModel processModel;
    Eigen::Vector3d imuVariance;
};
namespace Eigen {
inline void outputQuat(std::ostream &os, Quaterniond const &q) {
    os << "[" << q.w() << " (" << q.vec().transpose() << ")]";
}
std::ostream &operator<<(std::ostream &os, Quaterniond const &q) {
    outputQuat(os, q);
    return os;
}
} // namespace Eigen

namespace Catch {
template <> struct TypelistTypeNameTrait<kalman::QFirst> {
    static const char *get() { return "kalman::QFirst"; }
};
template <> struct TypelistTypeNameTrait<kalman::QLast> {
    static const char *get() { return "kalman::QLast"; }
};
template <> struct TypelistTypeNameTrait<kalman::SplitQ> {
    static const char *get() { return "kalman::SplitQ"; }
};
} // namespace Catch

static const double SMALL_VALUE = 0.1;
template <typename MeasurementType>
inline void smallPositiveYChecks(TestData *data, MeasurementType &kalmanMeas) {
    using JacobianType = typename MeasurementType::JacobianType;
    Vector3d residual = kalmanMeas.getResidual(data->state);
    AND_THEN("residual should be 0, SMALL_VALUE, 0") {
        CAPTURE(residual.transpose());
        CHECK(residual.isApprox(Vector3d(0, SMALL_VALUE, 0)));
    }

    JacobianType jacobian = kalmanMeas.getJacobian(data->state);
    AND_THEN("the jacobian should be finite") {
        INFO("jacobian\n" << jacobian);
        REQUIRE(jacobian.allFinite());
        AND_THEN("the jacobian should not be zero") {
            REQUIRE_FALSE(jacobian.isApproxToConstant(0));
        }
    }

    auto correctionInProgress =
        kalman::beginCorrection(data->state, data->processModel, kalmanMeas);
    AND_THEN("computed deltaz should equal residual") {
        CAPTURE(residual.transpose());
        CAPTURE(correctionInProgress.deltaz.transpose());
        CHECK(residual.isApprox(correctionInProgress.deltaz));
    }
    CAPTURE(correctionInProgress.stateCorrection.transpose());
    AND_THEN("state correction should be finite") {
        REQUIRE(correctionInProgress.stateCorrectionFinite);
        AND_THEN("state correction should have a rotation component with small "
                 "positive y") {
            REQUIRE(correctionInProgress.stateCorrection[3] == Approx(0.));
            REQUIRE(correctionInProgress.stateCorrection[4] > 0);
            REQUIRE(correctionInProgress.stateCorrection[5] == Approx(0.));
        }
        AND_THEN("state correction should have an angular velocity component "
                 "with zero or small positive y") {
            REQUIRE(correctionInProgress.stateCorrection[9] == Approx(0.));
            REQUIRE(correctionInProgress.stateCorrection[10] >= 0.);
            REQUIRE(correctionInProgress.stateCorrection[11] == Approx(0.));
        }
        AND_THEN("state correction should not contain any translational/linear "
                 "velocity components") {
            REQUIRE(correctionInProgress.stateCorrection.head<3>()
                        .isApproxToConstant(0.));
            REQUIRE(correctionInProgress.stateCorrection.segment<3>(6)
                        .isApproxToConstant(0.));
        }
    }
}

CATCH_TYPELIST_TESTCASE("identity calibration output", kalman::QFirst,
                        kalman::QLast, kalman::SplitQ) {
    using MeasurementType = OrientationMeasurementUsingPolicy<TypeParam>;
    using JacobianType = typename MeasurementType::JacobianType;
    unique_ptr<TestData> data(new TestData);
    GIVEN("an identity state") {
        WHEN("filtering in an identity measurement") {
            Quaterniond xformedMeas = data->xform(Quaterniond::Identity());

            THEN("the transformed measurement should equal the measurement") {
                CAPTURE(xformedMeas);
                REQUIRE(xformedMeas.isApprox(Quaterniond::Identity()));

                MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
                AND_THEN("residual should be zero") {
                    CAPTURE(kalmanMeas.getResidual(data->state));
                    REQUIRE(kalmanMeas.getResidual(data->state)
                                .isApproxToConstant(0.));
                }

                JacobianType jacobian = kalmanMeas.getJacobian(data->state);
                AND_THEN("the jacobian should be finite") {
                    INFO("jacobian\n" << jacobian);
                    REQUIRE(jacobian.allFinite());
                    AND_THEN("the jacobian should not be zero") {
                        REQUIRE_FALSE(jacobian.isApproxToConstant(0));
                    }
                    auto correctionInProgress = kalman::beginCorrection(
                        data->state, data->processModel, kalmanMeas);
                    AND_THEN("computed deltaz should be zero") {
                        CAPTURE(correctionInProgress.deltaz.transpose());
                        REQUIRE(
                            correctionInProgress.deltaz.isApproxToConstant(0.));
                    }
                    CAPTURE(correctionInProgress.stateCorrection.transpose());
                    AND_THEN("state correction should be finite") {
                        REQUIRE(correctionInProgress.stateCorrectionFinite);
                        AND_THEN("state correction should be zero") {
                            REQUIRE(correctionInProgress.stateCorrection
                                        .isApproxToConstant(0.));
                        }
                    }
                }
            }
        }
        WHEN("filtering in a small positive rotation about y") {
            Quaterniond smallPositiveRotationAboutY(
                AngleAxisd(SMALL_VALUE, Vector3d::UnitY()));
            CAPTURE(SMALL_VALUE);
            CAPTURE(smallPositiveRotationAboutY);
            Quaterniond xformedMeas = data->xform(smallPositiveRotationAboutY);
            CAPTURE(xformedMeas);

            THEN("the transformed measurement should equal the measurement") {
                REQUIRE(xformedMeas.isApprox(smallPositiveRotationAboutY));
                /// Do the rest of the checks for a small rotation about y
                MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
                smallPositiveYChecks(data.get(), kalmanMeas);
            }
        }
    }
    GIVEN("a state rotated about y") {
        Quaterniond stateRotation(AngleAxisd(M_PI / 4., Vector3d::UnitY()));
        data->state.setQuaternion(stateRotation);
        WHEN("filtering in a small positive rotation about y") {
            Quaterniond smallPositiveRotationAboutY =
                stateRotation *
                Quaterniond(AngleAxisd(SMALL_VALUE, Vector3d::UnitY()));
            CAPTURE(SMALL_VALUE);
            CAPTURE(smallPositiveRotationAboutY);
            Quaterniond xformedMeas = data->xform(smallPositiveRotationAboutY);
            CAPTURE(xformedMeas);

            THEN("the transformed measurement should equal the measurement") {
                REQUIRE(xformedMeas.isApprox(smallPositiveRotationAboutY));

                /// Do the rest of the checks for a small rotation about y
                MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
                smallPositiveYChecks(data.get(), kalmanMeas);
            }
        }
    }
    GIVEN("a state rotated about x") {
        Quaterniond stateRotation(AngleAxisd(M_PI / 4., Vector3d::UnitX()));
        data->state.setQuaternion(stateRotation);
        WHEN("filtering in a small positive rotation about y") {
            Quaterniond smallPositiveRotationAboutY =
                stateRotation *
                Quaterniond(AngleAxisd(SMALL_VALUE, Vector3d::UnitY()));
            CAPTURE(SMALL_VALUE);
            CAPTURE(smallPositiveRotationAboutY);
            Quaterniond xformedMeas = data->xform(smallPositiveRotationAboutY);
            CAPTURE(xformedMeas);

            THEN("the transformed measurement should equal the measurement") {
                REQUIRE(xformedMeas.isApprox(smallPositiveRotationAboutY));

                /// Do the rest of the checks for a small rotation about y
                MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
                smallPositiveYChecks(data.get(), kalmanMeas);
            }
        }
    }
}

TEST_CASE("Sigma point reconstruction validity") {
    using namespace osvr::kalman;
    Matrix3d cov(Vector3d::Constant(10).asDiagonal());
    using Generator = SigmaPointGenerator<3>;
    using Reconstructor = ReconstructedDistributionFromSigmaPoints<3, 3>;
    const auto params = SigmaPointParameters(3);
    WHEN("Starting with a zero mean") {
        Vector3d mean = Vector3d::Zero();
        auto gen = Generator(mean, cov, params);
        auto recon = Reconstructor(gen, gen.getSigmaPoints());
        THEN("the reconstructed distribution should be approximately equal to "
             "the input") {
            CAPTURE(gen.getSigmaPoints());
            CAPTURE(recon.getMean());
            REQUIRE(recon.getMean().isApproxToConstant(0));
            CAPTURE(recon.getCov());
            REQUIRE(recon.getCov().isApprox(cov));
        }
    }
}
<commit_msg>Unscented implementation in the testIMU file.<commit_after>/** @file
    @brief Implementation

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2016 Sensics, Inc.
//
// 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.

// Internal Includes
#include "ConfigParams.h"
#include "IMUStateMeasurements.h"

// Library/third-party includes
#include <osvr/Util/Angles.h>

// Standard includes
#include <iostream>
#include <memory>

#define CATCH_CONFIG_MAIN
#include "catch_typelist.h"
#include <catch.hpp>

using std::unique_ptr;
using namespace osvr;
using namespace vbtracker;
using namespace Eigen;
struct TestData {
    TestData() {
        /// Set up from a default configuration.
        ConfigParams params;
#if 0
        state.setErrorCovariance(
            kalman::types::DimVector<BodyState>::Constant(100).asDiagonal());
#endif

        /// configure the process model
        processModel.setDamping(params.linearVelocityDecayCoefficient,
                                params.angularVelocityDecayCoefficient);
        processModel.setNoiseAutocorrelation(
            kalman::types::Vector<6>::Map(params.processNoiseAutocorrelation));

        /// Save the IMU measurement parameters.
        imuVariance = Eigen::Vector3d::Constant(params.imu.orientationVariance);
    }
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
    /// Quantity computed from the "camera pose" (room calibration output)
    Eigen::Quaterniond roomToCameraRotation = Eigen::Quaterniond::Identity();

    /// Quantity computed during room calibration output
    util::Angle yawCorrection = 0;

    /// Transform the IMU-measured quaternion using the calibration output
    /// mocked up in this struct.
    Eigen::Quaterniond xform(Eigen::Quaterniond const &quat) {
        return getTransformedOrientation(quat, roomToCameraRotation,
                                         yawCorrection);
    }

    /// Default constructor is no translation, identity rotation, 10 along
    /// main diagonal as the state covariance matrix.
    BodyState state;

    BodyProcessModel processModel;
    Eigen::Vector3d imuVariance;
};
namespace Eigen {
inline void outputQuat(std::ostream &os, Quaterniond const &q) {
    os << "[" << q.w() << " (" << q.vec().transpose() << ")]";
}
std::ostream &operator<<(std::ostream &os, Quaterniond const &q) {
    outputQuat(os, q);
    return os;
}
} // namespace Eigen

namespace Catch {
template <> struct TypelistTypeNameTrait<kalman::QFirst> {
    static const char *get() { return "kalman::QFirst"; }
};
template <> struct TypelistTypeNameTrait<kalman::QLast> {
    static const char *get() { return "kalman::QLast"; }
};
template <> struct TypelistTypeNameTrait<kalman::SplitQ> {
    static const char *get() { return "kalman::SplitQ"; }
};
} // namespace Catch

static const double SMALL_VALUE = 0.1;
template <typename MeasurementType>
inline void smallPositiveYChecks(TestData *data, MeasurementType &kalmanMeas) {
    using JacobianType = typename MeasurementType::JacobianType;
    Vector3d residual = kalmanMeas.getResidual(data->state);
    AND_THEN("residual should be 0, SMALL_VALUE, 0") {
        CAPTURE(residual.transpose());
        CHECK(residual.isApprox(Vector3d(0, SMALL_VALUE, 0)));
    }

    JacobianType jacobian = kalmanMeas.getJacobian(data->state);
    AND_THEN("the jacobian should be finite") {
        INFO("jacobian\n" << jacobian);
        REQUIRE(jacobian.allFinite());
        AND_THEN("the jacobian should not be zero") {
            REQUIRE_FALSE(jacobian.isApproxToConstant(0));
        }
    }

    auto correctionInProgress =
        kalman::beginCorrection(data->state, data->processModel, kalmanMeas);
    AND_THEN("computed deltaz should equal residual") {
        CAPTURE(residual.transpose());
        CAPTURE(correctionInProgress.deltaz.transpose());
        CHECK(residual.isApprox(correctionInProgress.deltaz));
    }
    CAPTURE(correctionInProgress.stateCorrection.transpose());
    AND_THEN("state correction should be finite") {
        REQUIRE(correctionInProgress.stateCorrectionFinite);
        AND_THEN("state correction should have a rotation component with small "
                 "positive y") {
            REQUIRE(correctionInProgress.stateCorrection[3] == Approx(0.));
            REQUIRE(correctionInProgress.stateCorrection[4] > 0);
            REQUIRE(correctionInProgress.stateCorrection[5] == Approx(0.));
        }
        AND_THEN("state correction should have an angular velocity component "
                 "with zero or small positive y") {
            REQUIRE(correctionInProgress.stateCorrection[9] == Approx(0.));
            REQUIRE(correctionInProgress.stateCorrection[10] >= 0.);
            REQUIRE(correctionInProgress.stateCorrection[11] == Approx(0.));
        }
        AND_THEN("state correction should not contain any translational/linear "
                 "velocity components") {
            REQUIRE(correctionInProgress.stateCorrection.head<3>()
                        .isApproxToConstant(0.));
            REQUIRE(correctionInProgress.stateCorrection.segment<3>(6)
                        .isApproxToConstant(0.));
        }
    }
}

CATCH_TYPELIST_TESTCASE("identity calibration output", kalman::QFirst,
                        kalman::QLast, kalman::SplitQ) {
    using MeasurementType = OrientationMeasurementUsingPolicy<TypeParam>;
    using JacobianType = typename MeasurementType::JacobianType;
    unique_ptr<TestData> data(new TestData);
    GIVEN("an identity state") {
        WHEN("filtering in an identity measurement") {
            Quaterniond xformedMeas = data->xform(Quaterniond::Identity());

            THEN("the transformed measurement should equal the measurement") {
                CAPTURE(xformedMeas);
                REQUIRE(xformedMeas.isApprox(Quaterniond::Identity()));

                MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
                AND_THEN("residual should be zero") {
                    CAPTURE(kalmanMeas.getResidual(data->state));
                    REQUIRE(kalmanMeas.getResidual(data->state)
                                .isApproxToConstant(0.));
                }

                JacobianType jacobian = kalmanMeas.getJacobian(data->state);
                AND_THEN("the jacobian should be finite") {
                    INFO("jacobian\n" << jacobian);
                    REQUIRE(jacobian.allFinite());
                    AND_THEN("the jacobian should not be zero") {
                        REQUIRE_FALSE(jacobian.isApproxToConstant(0));
                    }
                    auto correctionInProgress = kalman::beginCorrection(
                        data->state, data->processModel, kalmanMeas);
                    AND_THEN("computed deltaz should be zero") {
                        CAPTURE(correctionInProgress.deltaz.transpose());
                        REQUIRE(
                            correctionInProgress.deltaz.isApproxToConstant(0.));
                    }
                    CAPTURE(correctionInProgress.stateCorrection.transpose());
                    AND_THEN("state correction should be finite") {
                        REQUIRE(correctionInProgress.stateCorrectionFinite);
                        AND_THEN("state correction should be zero") {
                            REQUIRE(correctionInProgress.stateCorrection
                                        .isApproxToConstant(0.));
                        }
                    }
                }
            }
        }
        WHEN("filtering in a small positive rotation about y") {
            Quaterniond smallPositiveRotationAboutY(
                AngleAxisd(SMALL_VALUE, Vector3d::UnitY()));
            CAPTURE(SMALL_VALUE);
            CAPTURE(smallPositiveRotationAboutY);
            Quaterniond xformedMeas = data->xform(smallPositiveRotationAboutY);
            CAPTURE(xformedMeas);

            THEN("the transformed measurement should equal the measurement") {
                REQUIRE(xformedMeas.isApprox(smallPositiveRotationAboutY));
                /// Do the rest of the checks for a small rotation about y
                MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
                smallPositiveYChecks(data.get(), kalmanMeas);
            }
        }
    }
    GIVEN("a state rotated about y") {
        Quaterniond stateRotation(AngleAxisd(M_PI / 4., Vector3d::UnitY()));
        data->state.setQuaternion(stateRotation);
        WHEN("filtering in a small positive rotation about y") {
            Quaterniond smallPositiveRotationAboutY =
                stateRotation *
                Quaterniond(AngleAxisd(SMALL_VALUE, Vector3d::UnitY()));
            CAPTURE(SMALL_VALUE);
            CAPTURE(smallPositiveRotationAboutY);
            Quaterniond xformedMeas = data->xform(smallPositiveRotationAboutY);
            CAPTURE(xformedMeas);

            THEN("the transformed measurement should equal the measurement") {
                REQUIRE(xformedMeas.isApprox(smallPositiveRotationAboutY));

                /// Do the rest of the checks for a small rotation about y
                MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
                smallPositiveYChecks(data.get(), kalmanMeas);
            }
        }
    }
    GIVEN("a state rotated about x") {
        Quaterniond stateRotation(AngleAxisd(M_PI / 4., Vector3d::UnitX()));
        data->state.setQuaternion(stateRotation);
        WHEN("filtering in a small positive rotation about y") {
            Quaterniond smallPositiveRotationAboutY =
                stateRotation *
                Quaterniond(AngleAxisd(SMALL_VALUE, Vector3d::UnitY()));
            CAPTURE(SMALL_VALUE);
            CAPTURE(smallPositiveRotationAboutY);
            Quaterniond xformedMeas = data->xform(smallPositiveRotationAboutY);
            CAPTURE(xformedMeas);

            THEN("the transformed measurement should equal the measurement") {
                REQUIRE(xformedMeas.isApprox(smallPositiveRotationAboutY));

                /// Do the rest of the checks for a small rotation about y
                MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
                smallPositiveYChecks(data.get(), kalmanMeas);
            }
        }
    }
}

TEST_CASE("Sigma point reconstruction validity") {
    using namespace osvr::kalman;
    Matrix3d cov(Vector3d::Constant(10).asDiagonal());
    using Generator = SigmaPointGenerator<3>;
    using Reconstructor = ReconstructedDistributionFromSigmaPoints<3, 3>;
    const auto params = SigmaPointParameters(3);
    WHEN("Starting with a zero mean") {
        Vector3d mean = Vector3d::Zero();
        auto gen = Generator(mean, cov, params);
        auto recon = Reconstructor(gen, gen.getSigmaPoints());
        THEN("the reconstructed distribution should be approximately equal to "
             "the input") {
            CAPTURE(gen.getSigmaPoints());
            CAPTURE(recon.getMean());
            REQUIRE(recon.getMean().isApproxToConstant(0));
            CAPTURE(recon.getCov());
            REQUIRE(recon.getCov().isApprox(cov));
        }
    }

    WHEN("Starting with a non-zero mean") {
        Vector3d mean = Vector3d(1, 2, 3);
        auto gen = Generator(mean, cov, params);
        auto recon = Reconstructor(gen, gen.getSigmaPoints());
        THEN("the reconstructed distribution should be approximately equal to "
             "the input") {
            CAPTURE(gen.getSigmaPoints());
            CAPTURE(recon.getMean());
            REQUIRE(recon.getMean().isApprox(mean));
            CAPTURE(recon.getCov());
            REQUIRE(recon.getCov().isApprox(cov));
        }
    }
}

namespace osvr {
namespace kalman {

    template <std::size_t Dim, std::size_t OrigDim = Dim>
    class AugmentedSigmaPointGenerator {
      public:
        static_assert(OrigDim <= Dim, "Original, non-augmented dimension must "
                                      "be equal or less than the full "
                                      "dimension");
        static const std::size_t L = Dim;
        static const std::size_t OriginalDimension = OrigDim;
        static const std::size_t NumSigmaPoints = L * 2 + 1;
        using MeanVec = types::Vector<Dim>;
        using CovMatrix = types::SquareMatrix<Dim>;
        using SigmaPointsMat = types::Matrix<Dim, NumSigmaPoints>;
        using SigmaPointWeightVec = types::Vector<NumSigmaPoints>;
        template <std::size_t OutputDimension>
        using TransformedSigmaPointsMat =
            types::Matrix<OutputDimension, NumSigmaPoints>;
        AugmentedSigmaPointGenerator(MeanVec const &mean, CovMatrix const &cov,
                                     SigmaPointParameters params)
            : mean_(mean), covariance_(cov) {
            weights_ =
                SigmaPointWeightVec::Constant(params.getOtherEltWeights());
            weightsForCov_ = weights_;
            weights_[0] = params.getElt0MeanWeight();
            weightsForCov_[0] = params.getElt0CovWeight();
            scaledMatrixSqrt_ = cov.llt().matrixL();
            scaledMatrixSqrt_ *= params.gamma;
            sigmaPoints_ << mean, scaledMatrixSqrt_.colwise() + mean,
                (-scaledMatrixSqrt_).colwise() + mean;
        }

        SigmaPointsMat const &getSigmaPoints() const { return sigmaPoints_; }

        using SigmaPointBlock = Eigen::Block<SigmaPointsMat, OrigDim, 1>;
        using ConstSigmaPointBlock =
            Eigen::Block<const SigmaPointsMat, OrigDim, 1>;

        ConstSigmaPointBlock getSigmaPoint(std::size_t i) const {
            return sigmaPoints_.block<OrigDim, 1>(0, i);
        }

        SigmaPointWeightVec const &getWeightsForMean() const {
            return weights_;
        }
        SigmaPointWeightVec const &getWeightsForCov() const {
            return weightsForCov_;
        }

        MeanVec const &getMean() const { return mean_; }

      private:
        MeanVec mean_;
        CovMatrix covariance_;
        CovMatrix scaledMatrixSqrt_;
        SigmaPointsMat sigmaPoints_;
        SigmaPointWeightVec weights_;
        SigmaPointWeightVec weightsForCov_;
    };

    template <std::size_t XformedDim, typename SigmaPointsGenType>
    class SigmaDistributionReconstruction {
      public:
        static const std::size_t DIMENSION = XformedDim;
        using SigmaPointsGen = SigmaPointsGenType;
        static const std::size_t NumSigmaPoints =
            SigmaPointsGen::NumSigmaPoints;

        static const types::DimensionType OriginalDimension =
            SigmaPointsGen::OriginalDimension;
        using TransformedSigmaPointsMat =
            typename SigmaPointsGen::template TransformedSigmaPointsMat<
                XformedDim>;

        using CrossCovMatrix = types::Matrix<OriginalDimension, DIMENSION>;

        using MeanVec = types::Vector<XformedDim>;
        using CovMat = types::SquareMatrix<XformedDim>;
        SigmaDistributionReconstruction(
            SigmaPointsGen const &sigmaPoints,
            TransformedSigmaPointsMat const &xformedPointsMat)
            : xformedCov_(CovMat::Zero()), crossCov_(CrossCovMatrix::Zero()) {
            /// weighted average
            xformedMean_ = xformedPointsMat * sigmaPoints.getWeightsForMean();
            TransformedSigmaPointsMat zeroMeanPoints =
                xformedPointsMat.colwise() - xformedMean_;

            for (std::size_t i = 0; i < NumSigmaPoints; ++i) {
                auto weight = sigmaPoints.getWeightsForCov()[i];
                xformedCov_ += weight * zeroMeanPoints.col(i) *
                               zeroMeanPoints.col(i).transpose();
                crossCov_ += weight * sigmaPoints.getSigmaPoint(i) *
                             zeroMeanPoints.col(i).transpose();
            }
        }

        MeanVec const &getMean() const { return xformedMean_; }
        CovMat const &getCov() const { return xformedCov_; }
        // matrix of cross-covariance between original and transformed (such as
        // state and measurement)
        CrossCovMatrix const &getCrossCov() const { return crossCov_; }

      private:
        MeanVec xformedMean_;
        CovMat xformedCov_;
        CrossCovMatrix crossCov_;
    };

    template <typename State, typename Measurement>
    class SigmaPointCorrectionApplication {
      public:
        static const types::DimensionType StateDim =
            types::Dimension<State>::value;
        static const types::DimensionType MeasurementDim =
            types::Dimension<Measurement>::value;
        /// state augmented with measurement noise mean
        static const types::DimensionType AugmentedStateDim =
            StateDim + MeasurementDim;
        using StateVec = types::DimVector<State>;
        using StateSquareMatrix = types::DimSquareMatrix<State>;
        using MeasurementSquareMatrix = types::DimSquareMatrix<Measurement>;
        using AugmentedStateVec = types::Vector<AugmentedStateDim>;
        using AugmentedStateCovMatrix = types::SquareMatrix<AugmentedStateDim>;
        using SigmaPointsGen =
            AugmentedSigmaPointGenerator<AugmentedStateDim, StateDim>;
        static const types::DimensionType NumSigmaPoints =
            SigmaPointsGen::NumSigmaPoints;

        using TransformedSigmaPointMat =
            types::Matrix<MeasurementDim, NumSigmaPoints>;

        using Reconstruction =
            SigmaDistributionReconstruction<MeasurementDim, SigmaPointsGen>;

        using GainMatrix = types::Matrix<StateDim, MeasurementDim>;

        SigmaPointCorrectionApplication(State &s, Measurement &m,
                                        SigmaPointParameters params)
            : state(s), measurement(m),
              sigmaPoints(getAugmentedStateVec(s, m),
                          getAugmentedStateCov(s, m), params),
              transformedPoints(
                  transformSigmaPoints(state, measurement, sigmaPoints)),
              reconstruction(sigmaPoints, transformedPoints),
              innovationCovariance(computeInnovationCovariance(
                  state, measurement, reconstruction)),
              K(computeKalmanGain(innovationCovariance, reconstruction)),
              stateCorrection(K * reconstruction.getMean()) {}

        static AugmentedStateVec getAugmentedStateVec(State const &s,
                                                      Measurement const &m) {
            AugmentedStateVec ret;
            /// assuming measurement noise is zero mean
            ret << s.stateVector(), types::DimVector<Measurement>::Zero();
            return ret;
        }

        static AugmentedStateCovMatrix getAugmentedStateCov(State const &s,
                                                            Measurement &m) {
            AugmentedStateCovMatrix ret;
            ret << s.errorCovariance(),
                types::Matrix<StateDim, MeasurementDim>::Zero(),
                types::Matrix<MeasurementDim, StateDim>::Zero(),
                m.getCovariance(s);
            return ret;
        }

        /// Transforms sigma points by having the measurement compute the
        /// residual for a state whose state vector we update to each of the
        /// sigma points in turn.
        static TransformedSigmaPointMat
        transformSigmaPoints(State const &s, Measurement &m,
                             SigmaPointsGen const &sigmaPoints) {
            TransformedSigmaPointMat ret;
            State tempS = s;
            for (std::size_t i = 0; i < NumSigmaPoints; ++i) {
                tempS.setStateVector(sigmaPoints.getSigmaPoint(i));
                ret.col(i) = m.getResidual(tempS);
            }
            return ret;
        }

        static MeasurementSquareMatrix
        computeInnovationCovariance(State const &s, Measurement &m,
                                    Reconstruction const &recon) {
            return recon.getCov() + m.getCovariance(s);
        }

        static GainMatrix computeKalmanGain(MeasurementSquareMatrix const &Pvv,
                                            Reconstruction const &recon) {

            // Solve for K in K=Pxy Pvv^-1
            // where the cross-covariance matrix from the reconstruction is
            // transpose(Pxy) and Pvv is the reconstructed covariance plus the
            // measurement covariance
            // (Actually solves with transpose(Pvv) * transpose(K) =
            // transpose(Pxy) )
            GainMatrix ret = Pvv.transpose().ldlt().solve(recon.getCrossCov());
            return ret;
        }

        void finishCorrection() {
            state.setStateVector(state.stateVector() + stateCorrection);

            StateSquareMatrix newP = state.errorCovariance() -
                                     K * innovationCovariance * K.transpose();
            state.setErrorCovariance(newP);
            // Let the state do any cleanup it has to (like fixing externalized
            // quaternions)
            state.postCorrect();
        }

        State &state;
        Measurement &measurement;
        SigmaPointsGen sigmaPoints;
        TransformedSigmaPointMat transformedPoints;
        Reconstruction reconstruction;
        MeasurementSquareMatrix innovationCovariance;
        GainMatrix K;
        StateVec stateCorrection;
    };
    template <typename State, typename Measurement>
    inline SigmaPointCorrectionApplication<State, Measurement>
    beginUnscentedCorrection(State &s, Measurement &m,
                             SigmaPointParameters params) {
        return SigmaPointCorrectionApplication<State, Measurement>(s, m,
                                                                   params);
    }
} // namespace kalman
} // namespace osvr
#if 0
CATCH_TYPELIST_TESTCASE("unscented with identity calibration output",
                        kalman::IMUOrientationMeasForUnscented) {
#endif
TEST_CASE("unscented with identity calibration output") {
    using TypeParam = kalman::IMUOrientationMeasForUnscented;

    const auto params = kalman::SigmaPointParameters(3);
    // using MeasurementType = OrientationMeasurementUsingPolicy<TypeParam>;
    using MeasurementType = TypeParam;
    unique_ptr<TestData> data(new TestData);
    GIVEN("an identity state") {
        WHEN("filtering in an identity measurement") {
            Quaterniond xformedMeas = data->xform(Quaterniond::Identity());

            THEN("the transformed measurement should equal the measurement") {
                CAPTURE(xformedMeas);
                REQUIRE(xformedMeas.isApprox(Quaterniond::Identity()));

                MeasurementType kalmanMeas{xformedMeas, data->imuVariance};
                AND_THEN("residual should be zero") {
                    CAPTURE(kalmanMeas.getResidual(data->state));
                    REQUIRE(kalmanMeas.getResidual(data->state)
                                .isApproxToConstant(0.));
                }
                using StateDim =
                    kalman::types::Dimension<decltype(data->state)>;
                using MeasurementDim =
                    kalman::types::Dimension<MeasurementType>;
                static const auto m = MeasurementDim::value;
                static const auto n = StateDim::value;
                auto inProgress = kalman::beginUnscentedCorrection(
                    data->state, kalmanMeas, params);

                AND_THEN("transformed sigma points should not all equal 0") {
                    REQUIRE_FALSE(
                        inProgress.transformedPoints.isApproxToConstant(0.));
                }
                // kalman::SigmaDistributionReconstruction<MeasurementDim::value,
                // typename decltype(inProgress)::SigmaPointsGen>
                auto &recon = inProgress.reconstruction;
                AND_THEN("propagated mean residual should be zero") {
                    CAPTURE(recon.getMean().transpose());
                    REQUIRE(recon.getMean().isApproxToConstant(0.));
                }
                AND_THEN(
                    "state correction should be finite - specifically, zero") {
                    CAPTURE(inProgress.stateCorrection.transpose());
                    REQUIRE(inProgress.stateCorrection.array().allFinite());
                    REQUIRE(inProgress.stateCorrection.isApproxToConstant(0));
                }
            }
        }
    }
}<|endoftext|>


<commit_before><commit_msg>Put back deprecated functions.<commit_after><|endoftext|>


<commit_before>#ifndef __GLOBALS_HPP_INCLUDED
#define __GLOBALS_HPP_INCLUDED

#include "any_value.hpp"

// GCC (at least g++ 4.7.2) and Visual Studio 2015 do support
// setting default values of a struct using C++11 syntax.
// Clang 3.7.0 and Visual Studio 2013 do not support
// setting default values of a struct using C++11 syntax.
// Visual Studio 2013 fails to compile, whereas Clang-compiled
// executable with code with setting default values of a struct
// causes Segmentation fault upon execution of the program.
// Compilers that don't support setting default values of a struct
// are handled by setting the default values in a macro.
// http://stackoverflow.com/questions/16782103/initializing-default-values-in-a-struct/16783513#16783513
#ifdef __clang__
#elif defined(__GNUC__)
#define __STRUCT_DEFAULT_VALUES_ARE_ACCEPTED
#elif defined(_WIN32)
#if (_MSC_VER >= 1900)
#define __STRUCT_DEFAULT_VALUES_ARE_ACCEPTED
#endif
#endif

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

// Include GLFW
#ifndef __GLFW3_H_INCLUDED
#define __GLFW3_H_INCLUDED
#include <glfw3.h>
#endif

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <cmath>    // NAN, std::isnan, std::pow
#include <stdint.h> // uint32_t etc.
#include <string>   // std::string
#include <vector>   // std::vector

#ifndef PI
#define PI 3.14159265359f
#endif

namespace ontology
{
    class Universe;
    class Scene;
    class Shader;
    class Graph;
    class Material;
    class VectorFont;
    class Species;
    class Glyph;
    class Text3D;
}

typedef struct ShaderStruct
{
    ShaderStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    ontology::Scene* parent_pointer; // pointer to the scene (draw list).
    std::string vertex_shader;    // filename of vertex shader.
    std::string fragment_shader;  // filename of fragment shader.
} ShaderStruct;

typedef struct MaterialStruct
{
    MaterialStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    ontology::Shader* parent_pointer;   // pointer to the shader.
    std::string texture_file_format; // type of the texture file. supported file formats so far: `"bmp"`/`"BMP"`, `"dds"`/`"DDS"`.
    std::string texture_filename;    // filename of the model file.
    std::string image_path;
} MaterialStruct;

typedef struct NodeStruct
{
    NodeStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    GLuint nodeID;
    ontology::Graph* parent_pointer;
    glm::vec3 coordinate_vector;
    std::vector<uint32_t> neighbor_nodeIDs;
} NodeStruct;

typedef struct ObjectStruct
{
    ObjectStruct()
        : species_parent_pointer(nullptr), glyph_parent_pointer(nullptr), text3D_parent_pointer(nullptr), original_scale_vector(glm::vec3(1.0f, 1.0f, 1.0f)), rotate_angle(NAN), is_character(false)
    {
        // constructor.
    }
    ontology::Species* species_parent_pointer; // pointer to the parent `Species`.
    ontology::Glyph* glyph_parent_pointer;     // pointer to the parent `Glyph`.
    ontology::Text3D* text3D_parent_pointer;   // pointer to the parent `Text3D`.
    glm::vec3 original_scale_vector; // original scale vector.
    GLfloat rotate_angle;            // rotate angle.
    bool is_character;               // The parent of a character object is a Glyph. The parent of a regular object is a Species.
    glm::vec3 coordinate_vector;     // coordinate vector.
    glm::vec3 rotate_vector;         // rotate vector.
    glm::vec3 translate_vector;      // translate vector.
} ObjectStruct;

typedef struct SpeciesStruct
{
    SpeciesStruct()
        : parent_pointer(nullptr), is_world(false), world_radius(NAN), triangulation_type("bilinear_interpolation")
    {
        // constructor.
    }
    // used for all files (for all species).
    ontology::Material* parent_pointer;         // pointer to the material object.
    bool is_world;                           // worlds currently do not rotate nor translate.
    double world_radius;                     // radius of sea level in meters. used only for worlds.
    std::string model_file_format;           // type of the model file. supported file formats so far: `"bmp"`/`"BMP"`, `"obj"`/`"OBJ"`.
                                             // TODO: add support for `"SRTM"`.
    std::string model_filename;              // filename of the model file.
    // for `"bmp"` model files.
    std::string color_channel;               // color channel to use for altitude data.

    glm::vec3 light_position;                // light position.
    std::string coordinate_system;           // used only for worlds (`is_world` == `true`). valid values: `"cartesian"`.
                                             // TODO: add support for `"spherical"`. `"spherical"` is used eg. in SRTM heightmaps.
    std::string triangulation_type;
} SpeciesStruct;

#define DEFAULT_VERTEX_SCALING_FACTOR (0.001f)

typedef struct VectorFontStruct
{
    VectorFontStruct()
        : parent_pointer(nullptr), vertex_scaling_factor(DEFAULT_VERTEX_SCALING_FACTOR)
    {
        // constructor.
    }
    // used for all files (for all font).
    ontology::Material* parent_pointer;        // pointer to the material object.
    GLfloat vertex_scaling_factor;
    std::string font_file_format;           // type of the font file. supported file formats so far: `"svg"`/`"SVG"`.
    std::string font_filename;              // filename of the font file.
} VectorFontStruct;

typedef struct Text3DStruct
{
    Text3DStruct()
        : parent_pointer(nullptr), original_scale_vector(glm::vec3(1.0f, 1.0f, 1.0f)), rotate_angle(NAN)
    {
        // constructor.
    }
    ontology::VectorFont* parent_pointer; // pointer to the parent `VectorFont`.
    std::string text_string;
    const char* text_string_char;
    glm::vec3 original_scale_vector;   // original scale vector.
    GLfloat rotate_angle;              // rotate angle.
    glm::vec3 coordinate_vector;       // coordinate vector.
    glm::vec3 rotate_vector;           // rotate vector.
    glm::vec3 translate_vector;        // translate vector.
} Text3DStruct;

typedef struct GlyphStruct
{
    GlyphStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    // used for all files (for all glyph).
    std::vector<std::vector<glm::vec2>>* glyph_vertex_data;
    const char* glyph_name_pointer;          // we need only a pointer, because glyphs are always created by the `VectorFont` constructor.
    const char* unicode_char_pointer;      // we need only a pointer, because glyphs are always created by the `VectorFont` constructor.
    ontology::VectorFont* parent_pointer;       // pointer to the font object.
    glm::vec3 light_position;                // light position.
} GlyphStruct;

typedef struct
{
    GLuint screen_width;
    GLuint screen_height;
    GLuint x;
    GLuint y;
    GLuint text_size;
    GLuint font_size;
    std::string text;
    const char* text_char;
    const char* char_font_texture_file_format;
    const char* horizontal_alignment;
    const char* vertical_alignment;
} PrintingStruct;

typedef struct
{
    double rho;
    double theta;
    double phi;
} SphericalCoordinatesStruct;

typedef struct SphericalWorldStruct
{
    SphericalWorldStruct()
        :SRTM_latitude_step_in_degrees(1.0f/1200.0f), SRTM_longitude_step_in_degrees(1.0f/1200.0f)
    {
        // constructor.
    }
    double southern_latitude;
    double northern_latitude;
    double western_longitude;
    double eastern_longitude;
    double SRTM_latitude_step_in_degrees;
    double SRTM_longitude_step_in_degrees;
} SphericalWorldStruct;

typedef struct TriangulateQuadsStruct
{
    TriangulateQuadsStruct()
        : should_ylikuutio_use_real_texture_coordinates(true)
    {
        // constructor.
    }
    uint32_t image_width;
    uint32_t image_height;
    std::string triangulation_type;
    bool should_ylikuutio_use_real_texture_coordinates;
    double sphere_radius;
    SphericalWorldStruct spherical_world_struct;
} TriangulateQuadsStruct;

typedef struct TriangulatePolygonsStruct
{
    TriangulatePolygonsStruct()
        : should_ylikuutio_use_real_texture_coordinates(true)
    {
        // constructor.
    }
    std::vector<std::vector<glm::vec2>>* input_vertices;
    bool should_ylikuutio_use_real_texture_coordinates;
} TriangulatePolygonsStruct;

typedef struct
{
    uint32_t image_width;
    uint32_t image_height;
    bool should_ylikuutio_use_real_texture_coordinates;
} BilinearInterpolationStruct;

typedef struct
{
    uint32_t image_width;
    uint32_t image_height;
    double sphere_radius;
    bool is_bilinear_interpolation_in_use;
    SphericalWorldStruct spherical_world_struct;
} TransformationStruct;

namespace callback_system
{
    class CallbackEngine;
    class CallbackObject;
    class CallbackParameter;
}
typedef datatypes::AnyValue* (*InputParametersToAnyValueCallback) (
        callback_system::CallbackEngine*,
        callback_system::CallbackObject*,
        std::vector<callback_system::CallbackParameter*>&);

namespace console
{
    class Console;
}
typedef datatypes::AnyValue* (*InputParametersToAnyValueCallbackWithConsole) (
        callback_system::CallbackEngine*,
        callback_system::CallbackObject*,
        std::vector<callback_system::CallbackParameter*>&,
        console::Console*);
#endif
<commit_msg>`typedef struct SpeciesStruct`, `world_radius`: `double` -> `float`.<commit_after>#ifndef __GLOBALS_HPP_INCLUDED
#define __GLOBALS_HPP_INCLUDED

#include "any_value.hpp"

// GCC (at least g++ 4.7.2) and Visual Studio 2015 do support
// setting default values of a struct using C++11 syntax.
// Clang 3.7.0 and Visual Studio 2013 do not support
// setting default values of a struct using C++11 syntax.
// Visual Studio 2013 fails to compile, whereas Clang-compiled
// executable with code with setting default values of a struct
// causes Segmentation fault upon execution of the program.
// Compilers that don't support setting default values of a struct
// are handled by setting the default values in a macro.
// http://stackoverflow.com/questions/16782103/initializing-default-values-in-a-struct/16783513#16783513
#ifdef __clang__
#elif defined(__GNUC__)
#define __STRUCT_DEFAULT_VALUES_ARE_ACCEPTED
#elif defined(_WIN32)
#if (_MSC_VER >= 1900)
#define __STRUCT_DEFAULT_VALUES_ARE_ACCEPTED
#endif
#endif

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

// Include GLFW
#ifndef __GLFW3_H_INCLUDED
#define __GLFW3_H_INCLUDED
#include <glfw3.h>
#endif

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <cmath>    // NAN, std::isnan, std::pow
#include <stdint.h> // uint32_t etc.
#include <string>   // std::string
#include <vector>   // std::vector

#ifndef PI
#define PI 3.14159265359f
#endif

namespace ontology
{
    class Universe;
    class Scene;
    class Shader;
    class Graph;
    class Material;
    class VectorFont;
    class Species;
    class Glyph;
    class Text3D;
}

typedef struct ShaderStruct
{
    ShaderStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    ontology::Scene* parent_pointer; // pointer to the scene (draw list).
    std::string vertex_shader;    // filename of vertex shader.
    std::string fragment_shader;  // filename of fragment shader.
} ShaderStruct;

typedef struct MaterialStruct
{
    MaterialStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    ontology::Shader* parent_pointer;   // pointer to the shader.
    std::string texture_file_format; // type of the texture file. supported file formats so far: `"bmp"`/`"BMP"`, `"dds"`/`"DDS"`.
    std::string texture_filename;    // filename of the model file.
    std::string image_path;
} MaterialStruct;

typedef struct NodeStruct
{
    NodeStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    GLuint nodeID;
    ontology::Graph* parent_pointer;
    glm::vec3 coordinate_vector;
    std::vector<uint32_t> neighbor_nodeIDs;
} NodeStruct;

typedef struct ObjectStruct
{
    ObjectStruct()
        : species_parent_pointer(nullptr), glyph_parent_pointer(nullptr), text3D_parent_pointer(nullptr), original_scale_vector(glm::vec3(1.0f, 1.0f, 1.0f)), rotate_angle(NAN), is_character(false)
    {
        // constructor.
    }
    ontology::Species* species_parent_pointer; // pointer to the parent `Species`.
    ontology::Glyph* glyph_parent_pointer;     // pointer to the parent `Glyph`.
    ontology::Text3D* text3D_parent_pointer;   // pointer to the parent `Text3D`.
    glm::vec3 original_scale_vector; // original scale vector.
    GLfloat rotate_angle;            // rotate angle.
    bool is_character;               // The parent of a character object is a Glyph. The parent of a regular object is a Species.
    glm::vec3 coordinate_vector;     // coordinate vector.
    glm::vec3 rotate_vector;         // rotate vector.
    glm::vec3 translate_vector;      // translate vector.
} ObjectStruct;

typedef struct SpeciesStruct
{
    SpeciesStruct()
        : parent_pointer(nullptr), is_world(false), world_radius(NAN), triangulation_type("bilinear_interpolation")
    {
        // constructor.
    }
    // used for all files (for all species).
    ontology::Material* parent_pointer;         // pointer to the material object.
    bool is_world;                           // worlds currently do not rotate nor translate.
    float world_radius;                      // radius of sea level in kilometers. used only for worlds.
    std::string model_file_format;           // type of the model file. supported file formats so far: `"bmp"`/`"BMP"`, `"obj"`/`"OBJ"`.
                                             // TODO: add support for `"SRTM"`.
    std::string model_filename;              // filename of the model file.
    // for `"bmp"` model files.
    std::string color_channel;               // color channel to use for altitude data.

    glm::vec3 light_position;                // light position.
    std::string coordinate_system;           // used only for worlds (`is_world` == `true`). valid values: `"cartesian"`.
                                             // TODO: add support for `"spherical"`. `"spherical"` is used eg. in SRTM heightmaps.
    std::string triangulation_type;
} SpeciesStruct;

#define DEFAULT_VERTEX_SCALING_FACTOR (0.001f)

typedef struct VectorFontStruct
{
    VectorFontStruct()
        : parent_pointer(nullptr), vertex_scaling_factor(DEFAULT_VERTEX_SCALING_FACTOR)
    {
        // constructor.
    }
    // used for all files (for all font).
    ontology::Material* parent_pointer;        // pointer to the material object.
    GLfloat vertex_scaling_factor;
    std::string font_file_format;           // type of the font file. supported file formats so far: `"svg"`/`"SVG"`.
    std::string font_filename;              // filename of the font file.
} VectorFontStruct;

typedef struct Text3DStruct
{
    Text3DStruct()
        : parent_pointer(nullptr), original_scale_vector(glm::vec3(1.0f, 1.0f, 1.0f)), rotate_angle(NAN)
    {
        // constructor.
    }
    ontology::VectorFont* parent_pointer; // pointer to the parent `VectorFont`.
    std::string text_string;
    const char* text_string_char;
    glm::vec3 original_scale_vector;   // original scale vector.
    GLfloat rotate_angle;              // rotate angle.
    glm::vec3 coordinate_vector;       // coordinate vector.
    glm::vec3 rotate_vector;           // rotate vector.
    glm::vec3 translate_vector;        // translate vector.
} Text3DStruct;

typedef struct GlyphStruct
{
    GlyphStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    // used for all files (for all glyph).
    std::vector<std::vector<glm::vec2>>* glyph_vertex_data;
    const char* glyph_name_pointer;          // we need only a pointer, because glyphs are always created by the `VectorFont` constructor.
    const char* unicode_char_pointer;      // we need only a pointer, because glyphs are always created by the `VectorFont` constructor.
    ontology::VectorFont* parent_pointer;       // pointer to the font object.
    glm::vec3 light_position;                // light position.
} GlyphStruct;

typedef struct
{
    GLuint screen_width;
    GLuint screen_height;
    GLuint x;
    GLuint y;
    GLuint text_size;
    GLuint font_size;
    std::string text;
    const char* text_char;
    const char* char_font_texture_file_format;
    const char* horizontal_alignment;
    const char* vertical_alignment;
} PrintingStruct;

typedef struct
{
    double rho;
    double theta;
    double phi;
} SphericalCoordinatesStruct;

typedef struct SphericalWorldStruct
{
    SphericalWorldStruct()
        :SRTM_latitude_step_in_degrees(1.0f/1200.0f), SRTM_longitude_step_in_degrees(1.0f/1200.0f)
    {
        // constructor.
    }
    double southern_latitude;
    double northern_latitude;
    double western_longitude;
    double eastern_longitude;
    double SRTM_latitude_step_in_degrees;
    double SRTM_longitude_step_in_degrees;
} SphericalWorldStruct;

typedef struct TriangulateQuadsStruct
{
    TriangulateQuadsStruct()
        : should_ylikuutio_use_real_texture_coordinates(true)
    {
        // constructor.
    }
    uint32_t image_width;
    uint32_t image_height;
    std::string triangulation_type;
    bool should_ylikuutio_use_real_texture_coordinates;
    double sphere_radius;
    SphericalWorldStruct spherical_world_struct;
} TriangulateQuadsStruct;

typedef struct TriangulatePolygonsStruct
{
    TriangulatePolygonsStruct()
        : should_ylikuutio_use_real_texture_coordinates(true)
    {
        // constructor.
    }
    std::vector<std::vector<glm::vec2>>* input_vertices;
    bool should_ylikuutio_use_real_texture_coordinates;
} TriangulatePolygonsStruct;

typedef struct
{
    uint32_t image_width;
    uint32_t image_height;
    bool should_ylikuutio_use_real_texture_coordinates;
} BilinearInterpolationStruct;

typedef struct
{
    uint32_t image_width;
    uint32_t image_height;
    double sphere_radius;
    bool is_bilinear_interpolation_in_use;
    SphericalWorldStruct spherical_world_struct;
} TransformationStruct;

namespace callback_system
{
    class CallbackEngine;
    class CallbackObject;
    class CallbackParameter;
}
typedef datatypes::AnyValue* (*InputParametersToAnyValueCallback) (
        callback_system::CallbackEngine*,
        callback_system::CallbackObject*,
        std::vector<callback_system::CallbackParameter*>&);

namespace console
{
    class Console;
}
typedef datatypes::AnyValue* (*InputParametersToAnyValueCallbackWithConsole) (
        callback_system::CallbackEngine*,
        callback_system::CallbackObject*,
        std::vector<callback_system::CallbackParameter*>&,
        console::Console*);
#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: gen_makefile.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-03-01 15:59:44 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"

#include "macro.hxx"
#include <stdio.h>

int main()
{
  printf( "RTL_OS:=%s\n", THIS_OS );
  printf( "RTL_ARCH:=%s\n", THIS_ARCH );
  return 0;
}

<commit_msg>INTEGRATION: CWS changefileheader (1.2.160); FILE MERGED 2008/03/31 13:24:02 rt 1.2.160.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: gen_makefile.cxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"

#include "macro.hxx"
#include <stdio.h>

int main()
{
  printf( "RTL_OS:=%s\n", THIS_OS );
  printf( "RTL_ARCH:=%s\n", THIS_ARCH );
  return 0;
}

<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.3  2000/02/06 07:47:31  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.2  2000/02/04 01:49:27  aruna1
 * TreeWalker and NodeIterator changes
 *
 * Revision 1.1.1.1  1999/11/09 01:09:05  twl
 * Initial checkin
 *
 * Revision 1.3  1999/11/08 20:44:22  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#ifndef DOM_TreeWalker_HEADER_GUARD_
#define DOM_TreeWalker_HEADER_GUARD_

#include "DOM_Node.hpp"
#include "DOM_NodeFilter.hpp"

class TreeWalkerImpl;

class CDOM_EXPORT DOM_TreeWalker {

    public:

    DOM_TreeWalker ();
    DOM_TreeWalker (TreeWalkerImpl* impl);
    DOM_TreeWalker(const DOM_TreeWalker &other);
    DOM_TreeWalker & operator = (const DOM_TreeWalker &other);
    DOM_TreeWalker & operator = (const DOM_NullPtr *val);
    ~DOM_TreeWalker();
    bool operator == (const DOM_TreeWalker & other)const;
    bool operator == (const DOM_NullPtr *other) const;
    bool operator != (const DOM_TreeWalker & other) const;
    bool operator != (const DOM_NullPtr * other) const;

    unsigned long   				getWhatToShow();
    DOM_NodeFilter*					getFilter();
    DOM_Node						getCurrentNode();
    void							setCurrentNode(DOM_Node currentNode);
    DOM_Node						parentNode();
    DOM_Node						firstChild();
    DOM_Node						lastChild();
    DOM_Node						previousSibling();
    DOM_Node						nextSibling();
    DOM_Node						previousNode();
    DOM_Node						nextNode();

    void							detach();

    private:
      TreeWalkerImpl*                 fImpl;
};

#endif
<commit_msg>Added API docs<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.4  2000/02/11 01:05:11  abagchi
 * Added API docs
 *
 * Revision 1.3  2000/02/06 07:47:31  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.2  2000/02/04 01:49:27  aruna1
 * TreeWalker and NodeIterator changes
 *
 * Revision 1.1.1.1  1999/11/09 01:09:05  twl
 * Initial checkin
 *
 * Revision 1.3  1999/11/08 20:44:22  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#ifndef DOM_TreeWalker_HEADER_GUARD_
#define DOM_TreeWalker_HEADER_GUARD_

#include "DOM_Node.hpp"
#include "DOM_NodeFilter.hpp"

class TreeWalkerImpl;

   /**
     * TreeWalker objects are used to navigate a document tree or subtree using the view of
     * the document defined by its whatToShow flags and any filters that are defined for the
     * TreeWalker. Any function which performs navigation using a TreeWalker will
     * automatically support any view defined by a TreeWalker.
     *
     * Omitting nodes from the logical view of a subtree can result in a structure that is
     * substantially different from the same subtree in the complete, unfiltered document. Nodes
     * that are siblings in the TreeWalker view may be children of different, widely separated
     * nodes in the original view. For instance, consider a Filter that skips all nodes except for
     * Text nodes and the root node of a document. In the logical view that results, all text
     * nodes will be siblings and appear as direct children of the root node, no matter how
     * deeply nested the structure of the original document.
     */

class CDOM_EXPORT DOM_TreeWalker {

    public:

        /** @name Constructors */
        //@{

        /**
          * Default constructor
          */
        DOM_TreeWalker ();

        /**
          * Copy constructor
          * @param other The object to be copied
          */
        DOM_TreeWalker(const DOM_TreeWalker &other);
        //@}

        /** @name Destructor */
        //@{
        /**
          * Destructor
          */
        ~DOM_TreeWalker();
        //@}

        /** @name Assignment operators */
        //@{
        /**
          * Assignment operator
          * @param other The object to be copied through assignment
          */
        DOM_TreeWalker & operator = (const DOM_TreeWalker &other);

        /**
          * Assignment operator
          *
          *   This overloaded variant is provided for
          *   the sole purpose of setting a DOM_Node reference variable to
          *   zero.  Nulling out a reference variable in this way will decrement
          *   the reference count on the underlying Node object that the variable
          *   formerly referenced.  This effect is normally obtained when reference
          *   variable goes out of scope, but zeroing them can be useful for
          *   global instances, or for local instances that will remain in scope
          *   for an extended time,  when the storage belonging to the underlying
          *   node needs to be reclaimed.
          * @param val Only a value of 0, or null, is allowed.
          */
        DOM_TreeWalker & operator = (const DOM_NullPtr *val);
        //@}

        /** @name Equality operators */
        //@{
        /**
         *  Test whether this TreeWalker reference refers to the same underlying
         *  tree walker as the other reference object.  This does not
         *  compare the contents of two different objects.
         *
         *  @param other The value to be compared
         *  @return Returns true if the underlying tree walker object is same
         */
        bool operator == (const DOM_TreeWalker & other)const;

        /**
         *  Use this comparison operator to test whether a tree walker reference
         *  is null.
         *
         *  @param other The value to be compared, which must be 0 or null.
         *  @return Returns true if the node iterator is null
         */
        bool operator == (const DOM_NullPtr *other) const;
        //@}

        /** @name Inequality operators */
        //@{

        /**
         *  Test whether this TreeWalker reference refers to the same underlying
         *  tree walker as the other reference object.  This does not
         *  compare the contents of two different objects.
         *
         *  @param other The value to be compared
         *  @return Returns true if the underlying tree walker is different
         */
        bool operator != (const DOM_TreeWalker & other) const;

        /**
         *  Use this comparison operator to test whether a tree walker reference
         *  is null.
         *
         *  @param other The value to be compared, which must be 0 or null.
         *  @return Returns true if the node iterator is NOT null
         */
        bool operator != (const DOM_NullPtr * other) const;
        //@}

        /** @name Get Functions */
        //@{
        /**
          *	 Returns the value of whatToShow
          *  This attribute determines which node types are presented via the
          *  TreeWalker. The available set of constants is defined in the Filters
          *  interface.
          */
        unsigned long   				getWhatToShow();
        /**
          *	Get the filter used to screen nodes.
          */
        DOM_NodeFilter*					getFilter();
        /**
          * Gets the node at which the tree walker is currently positioned.
          *
          * The value must not be null. Alterations to the DOM tree may cause the
          * current node to no longer be accepted by the TreeWalker's associated
          * filter. currentNode may also be explicitly set to any node, whether or not it
          * is within the subtree specified by the root node or would be accepted by
          * the filter and whatToShow flags. Further traversal occurs relative to
          * currentNode even if it is not part of the current view by applying the filters
          * in the requested direction (not changing currentNode where no traversal is
          * possible).
          */
        DOM_Node						getCurrentNode();
        //@}

        /** @name Set Functions */
        //@{
        /**
          *  Sets the current node of the DOM tree in tree walker
          *
          * To know more about the current node see getCurrentNode description.
          * @see #getCurrentNode
          */
        void							setCurrentNode(DOM_Node currentNode);
        //@}

        /** @name Iterator Methods */
        //@{

        /**
          * Moves to and returns the closest visible ancestor node of the current node.
          * If the search for parentNode attempts to step upward from the
          * TreeWalker's root node, or if it fails to find a visible ancestor node, this
          * method retains the current position and returns null.
          *
          * @return The new parent node, or null if the current node has no parent in
          *         the TreeWalker's logical view.
          */
        DOM_Node						parentNode();

        /**
          * Moves the TreeWalker to the first child of the current node, and returns the new node.
          * If the current node has no children, returns null, and retains
          * the current node
          * @return       The new node, or null if the current node has no children.
          */
        DOM_Node						firstChild();

        /**
          * Moves the TreeWalker to the last child of the current node, and returns the new node.
          * If the current node has no children, returns null, and retains
          * the current node.
          *
          * @return The new node, or null if the current node has no children.
          */
        DOM_Node						lastChild();

        /**
          * Moves the TreeWalker to the previous sibling of the current node, and returns the new node.
          * If the current node has no previous sibling, returns
          * null, and retains the current node.
          *
          * @return  The new node, or null if the current node has no previous sibling.
          */
        DOM_Node						previousSibling();

        /**
          * Moves the TreeWalker to the next sibling of the current node, and returns the new node.
          * If the current node has no next sibling, returns null, and
          * retains the current node.
          *
          * @return The new node, or null if the current node has no next sibling.
          */
        DOM_Node						nextSibling();

        /**
          * Moves the TreeWalker to the previous visible node in document order relative to the current node, and returns the new node.
          * If the current node
          * has no previous node, or if the search for previousNode attempts to step
          * upward from the TreeWalker's root node, returns null, and retains the
          * current node.
          *
          * @return  The new node, or null if the current node has no previous node.
          */
        DOM_Node						previousNode();

        /**
          * Moves the TreeWalker to the next visible node in document order relative to the current node, and returns the new node.
          * If the current node has no
          * next node, or if the search for nextNode attempts to step upward from the
          * TreeWalker's root node, returns null, and retains the current node.
          * @return The new node, or null if the current node has no next node.
          */
        DOM_Node						nextNode();

        /**
          *	 Detaches the iterator from the set which it iterated over, releasing any computational resources and placing the iterator in the INVALID state.
          *  After detach has been invoked, calls to nextNode or previousNode
          *  will raise the exception INVALID_STATE_ERR.
          */
        void							detach();
        //@}

    private:
        TreeWalkerImpl*                 fImpl;

    protected:
        DOM_TreeWalker (TreeWalkerImpl* impl);
};

#endif
<|endoftext|>