<commit_before>/*
 * Copyright (c) 2015, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Michael X. Grey <mxgrey@gatech.edu>
 *
 * Georgia Tech Graphics Lab and Humanoid Robotics Lab
 *
 * Directed by Prof. C. Karen Liu and Prof. Mike Stilman
 * <karenliu@cc.gatech.edu> <mstilman@cc.gatech.edu>
 *
 * This file is provided under the following "BSD-style" License:
 *   Redistribution and use in source and binary forms, with or
 *   without modification, are permitted provided that the following
 *   conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 *   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *   POSSIBILITY OF SUCH DAMAGE.
 */

#include "dart/dart.h"

const double default_domino_height = 0.3;
const double default_domino_width = 0.4 * default_domino_height;
const double default_domino_depth = default_domino_width / 5.0;

const double default_distance = default_domino_height / 2.0;
const double default_angle = 20.0 * M_PI / 180.0;

const double default_domino_density = 2.6e3; // kg/m^3
const double default_domino_mass =
    default_domino_density
    * default_domino_height
    * default_domino_width
    * default_domino_depth;

const double default_push_force = 8.0;  // N
const int default_force_duration = 200; // # iterations
const int default_push_duration = 1000;  // # iterations

const double defaultmEndEffectormOffset = 0.05;

using namespace dart::dynamics;
using namespace dart::simulation;
using namespace dart::math;

class Controller
{
public:

  Controller(const SkeletonPtr& manipulator, const SkeletonPtr& domino)
    : mManipulator(manipulator)
  {
    // Grab the current joint angles to use them as desired angles
    // Lesson 2b

    // Grab the last body in the manipulator, and use it as an end effector
    // Lesson 3a

    // Compute the body frame offset for the end effector
    // Lesson 3b

    // Create a transform from the center of the domino to the top of the domino
    // Lesson 3c

    // Rotate the transform so that it matches the orientation of the end
    // effector
    // Lesson 3d

    // Place the mTarget SimpleFrame at the top of the domino
    // Lesson 3e

    // Set PD control gains
    mKpPD = 200.0;
    mKdPD =  20.0;

    // Set operational space control gains
    mKpOS = 5.0;
    mKdOS = 0.01;
  }

  /// Compute a stable PD controller that also compensates for gravity and
  /// Coriolis forces
  void setPDForces()
  {
    // Lesson 2a

    // Lesson 2c
  }

  /// Compute an operational space controller to push on the first domino
  void setOperationalSpaceForces()
  {
    // Lesson 3f
  }

protected:

  /// The manipulator Skeleton that we will be controlling
  SkeletonPtr mManipulator;

  /// The target pose for the controller
  SimpleFramePtr mTarget;

  /// End effector for the manipulator
  BodyNodePtr mEndEffector;

  /// Desired joint positions when not applying the operational space controller
  Eigen::VectorXd mQDesired;

  /// The offset of the end effector from the body origin of the last BodyNode
  /// in the manipulator
  Eigen::Vector3d mOffset;

  /// Control gains for the proportional error terms in the PD controller
  double mKpPD;

  /// Control gains for the derivative error terms in the PD controller
  double mKdPD;

  /// Control gains for the proportional error terms in the operational
  /// space controller
  double mKpOS;

  /// Control gains for the derivative error terms in the operational space
  /// controller
  double mKdOS;

  /// Joint forces for the manipulator (output of the Controller)
  Eigen::VectorXd mForces;
};

class MyWindow : public dart::gui::SimWindow
{
public:

  MyWindow(const WorldPtr& world)
    : mTotalAngle(0.0),
      mHasEverRun(false),
      mForceCountDown(0),
      mPushCountDown(0)
  {
    setWorld(world);
    mFirstDomino = world->getSkeleton("domino");
    mFloor = world->getSkeleton("floor");

    mController = std::unique_ptr<Controller>(
          new Controller(world->getSkeleton("manipulator"), mFirstDomino));
  }

  // Attempt to create a new domino. If the new domino would be in collision
  // with anything (other than the floor), then discard it.
  void attemptToCreateDomino(double)
  {
    // Create the new domino
    // Lesson 1a

    // Look through the collisions to see if any dominoes are penetrating
    // something
    // Lesson 1b
  }

  // Delete the last domino that was added to the scene. (Do not delete the
  // original domino)
  void deleteLastDomino()
  {
    // Lesson 1c
  }

  void keyboard(unsigned char key, int x, int y) override
  {
    if(!mHasEverRun)
    {
      switch(key)
      {
        case 'q':
          attemptToCreateDomino( default_angle);
          break;
        case 'w':
          attemptToCreateDomino(0.0);
          break;
        case 'e':
          attemptToCreateDomino(-default_angle);
          break;
        case 'd':
          deleteLastDomino();
          break;
        case ' ':
          mHasEverRun = true;
          break;
      }
    }
    else
    {
      switch(key)
      {
        case 'f':
          mForceCountDown = default_force_duration;
          break;

        case 'r':
          mPushCountDown = default_push_duration;
          break;
      }
    }

    SimWindow::keyboard(key, x, y);
  }

  void timeStepping() override
  {
    // If the user has pressed the 'f' key, apply a force to the first domino in
    // order to push it over
    if(mForceCountDown > 0)
    {
      // Lesson 1d
      --mForceCountDown;
    }

    // Run the controller for the manipulator
    if(mPushCountDown > 0)
    {
      mController->setOperationalSpaceForces();
      --mPushCountDown;
    }
    else
    {
      mController->setPDForces();
    }

    SimWindow::timeStepping();
  }

protected:

  /// Base domino. Used to clone new dominoes.
  SkeletonPtr mFirstDomino;

  /// Floor of the scene
  SkeletonPtr mFloor;

  /// History of the dominoes that have been created
  std::vector<SkeletonPtr> mDominoes;

  /// History of the angles that the user has specified
  std::vector<double> mAngles;

  /// Sum of all angles so far
  double mTotalAngle;

  /// Set to true the first time spacebar is pressed
  bool mHasEverRun;

  /// The first domino will be pushed by a disembodied force while the value of
  /// this is greater than zero
  int mForceCountDown;

  /// The manipulator will attempt to push on the first domino while the value
  /// of this is greater than zero
  int mPushCountDown;

  std::unique_ptr<Controller> mController;

};

SkeletonPtr createDomino()
{
  // Create a Skeleton with the name "domino"
  SkeletonPtr domino = Skeleton::create("domino");

  // Create a body for the domino
  BodyNodePtr body =
      domino->createJointAndBodyNodePair<FreeJoint>(nullptr).second;

  // Create a shape for the domino
  std::shared_ptr<BoxShape> box(
        new BoxShape(Eigen::Vector3d(default_domino_depth,
                                     default_domino_width,
                                     default_domino_height)));
  body->addVisualizationShape(box);
  body->addCollisionShape(box);

  // Set up inertia for the domino
  dart::dynamics::Inertia inertia;
  inertia.setMass(default_domino_mass);
  inertia.setMoment(box->computeInertia(default_domino_mass));
  body->setInertia(inertia);

  domino->getDof("Joint_pos_z")->setPosition(default_domino_height / 2.0);

  return domino;
}

SkeletonPtr createFloor()
{
  SkeletonPtr floor = Skeleton::create("floor");

  // Give the floor a body
  BodyNodePtr body =
      floor->createJointAndBodyNodePair<WeldJoint>(nullptr).second;

  // Give the body a shape
  double floor_width = 10.0;
  double floor_height = 0.01;
  std::shared_ptr<BoxShape> box(
        new BoxShape(Eigen::Vector3d(floor_width, floor_width, floor_height)));
  box->setColor(dart::Color::Black());

  body->addVisualizationShape(box);
  body->addCollisionShape(box);

  // Put the body into position
  Eigen::Isometry3d tf(Eigen::Isometry3d::Identity());
  tf.translation() = Eigen::Vector3d(0.0, 0.0, -floor_height / 2.0);
  body->getParentJoint()->setTransformFromParentBodyNode(tf);

  return floor;
}

SkeletonPtr createManipulator()
{
  // Load the Skeleton from a file
  dart::utils::DartLoader loader;
  SkeletonPtr manipulator =
      loader.parseSkeleton(DART_DATA_PATH"urdf/KR5/KR5 sixx R650.urdf");
  manipulator->setName("manipulator");

  // Position its base in a reasonable way
  Eigen::Isometry3d tf = Eigen::Isometry3d::Identity();
  tf.translation() = Eigen::Vector3d(-0.65, 0.0, 0.0);
  manipulator->getJoint(0)->setTransformFromParentBodyNode(tf);

  // Get it into a useful configuration
  manipulator->getDof(1)->setPosition( 140.0*M_PI/180.0);
  manipulator->getDof(2)->setPosition(-140.0*M_PI/180.0);

  return manipulator;
}

int main(int argc, char* argv[])
{
  SkeletonPtr domino = createDomino();
  SkeletonPtr floor = createFloor();
  SkeletonPtr manipulator = createManipulator();

  WorldPtr world = std::make_shared<World>();
  world->addSkeleton(domino);
  world->addSkeleton(floor);
  world->addSkeleton(manipulator);

  MyWindow window(world);

  std::cout << "Before simulation has started, you can create new dominoes:" << std::endl;
  std::cout << "'w': Create new domino angled forward" << std::endl;
  std::cout << "'q': Create new domino angled to the left" << std::endl;
  std::cout << "'e': Create new domino angled to the right" << std::endl;
  std::cout << "'d': Delete the last domino that was created" << std::endl;
  std::cout << std::endl;
  std::cout << "spacebar: Begin simulation (you can no longer create or remove dominoes)" << std::endl;
  std::cout << "'p': replay simulation" << std::endl;
  std::cout << "'f': Push the first domino with a disembodies force so that it falls over" << std::endl;
  std::cout << "'r': Push the first domino with the manipulator so that it falls over" << std::endl;
  std::cout << "'v': Turn contact force visualization on/off" << std::endl;

  glutInit(&argc, argv);
  window.initWindow(640, 480, "Dominoes");
  glutMainLoop();
}
<commit_msg>added manipulator loading as a lesson<commit_after>/*
 * Copyright (c) 2015, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Michael X. Grey <mxgrey@gatech.edu>
 *
 * Georgia Tech Graphics Lab and Humanoid Robotics Lab
 *
 * Directed by Prof. C. Karen Liu and Prof. Mike Stilman
 * <karenliu@cc.gatech.edu> <mstilman@cc.gatech.edu>
 *
 * This file is provided under the following "BSD-style" License:
 *   Redistribution and use in source and binary forms, with or
 *   without modification, are permitted provided that the following
 *   conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 *   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *   POSSIBILITY OF SUCH DAMAGE.
 */

#include "dart/dart.h"

const double default_domino_height = 0.3;
const double default_domino_width = 0.4 * default_domino_height;
const double default_domino_depth = default_domino_width / 5.0;

const double default_distance = default_domino_height / 2.0;
const double default_angle = 20.0 * M_PI / 180.0;

const double default_domino_density = 2.6e3; // kg/m^3
const double default_domino_mass =
    default_domino_density
    * default_domino_height
    * default_domino_width
    * default_domino_depth;

const double default_push_force = 8.0;  // N
const int default_force_duration = 200; // # iterations
const int default_push_duration = 1000;  // # iterations

const double defaultmEndEffectormOffset = 0.05;

using namespace dart::dynamics;
using namespace dart::simulation;
using namespace dart::math;

class Controller
{
public:

  Controller(const SkeletonPtr& manipulator, const SkeletonPtr& /*domino*/)
    : mManipulator(manipulator)
  {
    // Grab the current joint angles to use them as desired angles
    // Lesson 2c

    // Grab the last body in the manipulator, and use it as an end effector
    // Lesson 3a

    // Compute the body frame offset for the end effector
    // Lesson 3b

    // Create a transform from the center of the domino to the top of the domino
    // Lesson 3c

    // Rotate the transform so that it matches the orientation of the end
    // effector
    // Lesson 3d

    // Place the mTarget SimpleFrame at the top of the domino
    // Lesson 3e

    // Set PD control gains
    mKpPD = 200.0;
    mKdPD =  20.0;

    // Set operational space control gains
    mKpOS = 5.0;
    mKdOS = 0.01;
  }

  /// Compute a stable PD controller that also compensates for gravity and
  /// Coriolis forces
  void setPDForces()
  {
    // Lesson 2b

    // Lesson 2d
  }

  /// Compute an operational space controller to push on the first domino
  void setOperationalSpaceForces()
  {
    // Lesson 3f
  }

protected:

  /// The manipulator Skeleton that we will be controlling
  SkeletonPtr mManipulator;

  /// The target pose for the controller
  SimpleFramePtr mTarget;

  /// End effector for the manipulator
  BodyNodePtr mEndEffector;

  /// Desired joint positions when not applying the operational space controller
  Eigen::VectorXd mQDesired;

  /// The offset of the end effector from the body origin of the last BodyNode
  /// in the manipulator
  Eigen::Vector3d mOffset;

  /// Control gains for the proportional error terms in the PD controller
  double mKpPD;

  /// Control gains for the derivative error terms in the PD controller
  double mKdPD;

  /// Control gains for the proportional error terms in the operational
  /// space controller
  double mKpOS;

  /// Control gains for the derivative error terms in the operational space
  /// controller
  double mKdOS;

  /// Joint forces for the manipulator (output of the Controller)
  Eigen::VectorXd mForces;
};

class MyWindow : public dart::gui::SimWindow
{
public:

  MyWindow(const WorldPtr& world)
    : mTotalAngle(0.0),
      mHasEverRun(false),
      mForceCountDown(0),
      mPushCountDown(0)
  {
    setWorld(world);
    mFirstDomino = world->getSkeleton("domino");
    mFloor = world->getSkeleton("floor");

    mController = std::unique_ptr<Controller>(
          new Controller(world->getSkeleton("manipulator"), mFirstDomino));
  }

  // Attempt to create a new domino. If the new domino would be in collision
  // with anything (other than the floor), then discard it.
  void attemptToCreateDomino(double)
  {
    // Create the new domino
    // Lesson 1a

    // Look through the collisions to see if any dominoes are penetrating
    // something
    // Lesson 1b
  }

  // Delete the last domino that was added to the scene. (Do not delete the
  // original domino)
  void deleteLastDomino()
  {
    // Lesson 1c
  }

  void keyboard(unsigned char key, int x, int y) override
  {
    if(!mHasEverRun)
    {
      switch(key)
      {
        case 'q':
          attemptToCreateDomino( default_angle);
          break;
        case 'w':
          attemptToCreateDomino(0.0);
          break;
        case 'e':
          attemptToCreateDomino(-default_angle);
          break;
        case 'd':
          deleteLastDomino();
          break;
        case ' ':
          mHasEverRun = true;
          break;
      }
    }
    else
    {
      switch(key)
      {
        case 'f':
          mForceCountDown = default_force_duration;
          break;

        case 'r':
          mPushCountDown = default_push_duration;
          break;
      }
    }

    SimWindow::keyboard(key, x, y);
  }

  void timeStepping() override
  {
    // If the user has pressed the 'f' key, apply a force to the first domino in
    // order to push it over
    if(mForceCountDown > 0)
    {
      // Lesson 1d
      --mForceCountDown;
    }

    // Run the controller for the manipulator
    if(mPushCountDown > 0)
    {
      mController->setOperationalSpaceForces();
      --mPushCountDown;
    }
    else
    {
      mController->setPDForces();
    }

    SimWindow::timeStepping();
  }

protected:

  /// Base domino. Used to clone new dominoes.
  SkeletonPtr mFirstDomino;

  /// Floor of the scene
  SkeletonPtr mFloor;

  /// History of the dominoes that have been created
  std::vector<SkeletonPtr> mDominoes;

  /// History of the angles that the user has specified
  std::vector<double> mAngles;

  /// Sum of all angles so far
  double mTotalAngle;

  /// Set to true the first time spacebar is pressed
  bool mHasEverRun;

  /// The first domino will be pushed by a disembodied force while the value of
  /// this is greater than zero
  int mForceCountDown;

  /// The manipulator will attempt to push on the first domino while the value
  /// of this is greater than zero
  int mPushCountDown;

  std::unique_ptr<Controller> mController;

};

SkeletonPtr createDomino()
{
  // Create a Skeleton with the name "domino"
  SkeletonPtr domino = Skeleton::create("domino");

  // Create a body for the domino
  BodyNodePtr body =
      domino->createJointAndBodyNodePair<FreeJoint>(nullptr).second;

  // Create a shape for the domino
  std::shared_ptr<BoxShape> box(
        new BoxShape(Eigen::Vector3d(default_domino_depth,
                                     default_domino_width,
                                     default_domino_height)));
  body->addVisualizationShape(box);
  body->addCollisionShape(box);

  // Set up inertia for the domino
  dart::dynamics::Inertia inertia;
  inertia.setMass(default_domino_mass);
  inertia.setMoment(box->computeInertia(default_domino_mass));
  body->setInertia(inertia);

  domino->getDof("Joint_pos_z")->setPosition(default_domino_height / 2.0);

  return domino;
}

SkeletonPtr createFloor()
{
  SkeletonPtr floor = Skeleton::create("floor");

  // Give the floor a body
  BodyNodePtr body =
      floor->createJointAndBodyNodePair<WeldJoint>(nullptr).second;

  // Give the body a shape
  double floor_width = 10.0;
  double floor_height = 0.01;
  std::shared_ptr<BoxShape> box(
        new BoxShape(Eigen::Vector3d(floor_width, floor_width, floor_height)));
  box->setColor(dart::Color::Black());

  body->addVisualizationShape(box);
  body->addCollisionShape(box);

  // Put the body into position
  Eigen::Isometry3d tf(Eigen::Isometry3d::Identity());
  tf.translation() = Eigen::Vector3d(0.0, 0.0, -floor_height / 2.0);
  body->getParentJoint()->setTransformFromParentBodyNode(tf);

  return floor;
}

SkeletonPtr createManipulator()
{
  // Lesson 2a
  return Skeleton::create("manipulator");
}

int main(int argc, char* argv[])
{
  SkeletonPtr domino = createDomino();
  SkeletonPtr floor = createFloor();
  SkeletonPtr manipulator = createManipulator();

  WorldPtr world = std::make_shared<World>();
  world->addSkeleton(domino);
  world->addSkeleton(floor);
  world->addSkeleton(manipulator);

  MyWindow window(world);

  std::cout << "Before simulation has started, you can create new dominoes:" << std::endl;
  std::cout << "'w': Create new domino angled forward" << std::endl;
  std::cout << "'q': Create new domino angled to the left" << std::endl;
  std::cout << "'e': Create new domino angled to the right" << std::endl;
  std::cout << "'d': Delete the last domino that was created" << std::endl;
  std::cout << std::endl;
  std::cout << "spacebar: Begin simulation (you can no longer create or remove dominoes)" << std::endl;
  std::cout << "'p': replay simulation" << std::endl;
  std::cout << "'f': Push the first domino with a disembodies force so that it falls over" << std::endl;
  std::cout << "'r': Push the first domino with the manipulator so that it falls over" << std::endl;
  std::cout << "'v': Turn contact force visualization on/off" << std::endl;

  glutInit(&argc, argv);
  window.initWindow(640, 480, "Dominoes");
  glutMainLoop();
}
<|endoftext|>


<commit_before>/*-------------simple.cpp-----------------------------------------------------//
*
* Purpose: This file is a simple example of how we can simulate the defomation
*          of balls with a newton-solver algorithm. I have referred to RK4 a
*          few tiems and may implement it if this ends up becoming too slow in
*          the future, but I think it should be fine.
*
*-----------------------------------------------------------------------------*/

#include <iostream>
#include <vector>
#include <cmath>

/*----------------------------------------------------------------------------//
* STRUCTURES AND FUNCTIONS
*-----------------------------------------------------------------------------*/
using namespace std;

// Structure to point to the closest points in each direction
// I might actually use pointer later, but not for now.
struct closest{
    int up,down,forw,back,left,right;
};

// Class to hold all values of particles.
class point{
    public:
        int step_num;                                  // Time-step number.
        double x, y, z;                                // Position in x, y, z
        double v_x, v_y, v_z;                          // Velocity in x, y, z
        closest next;                                  // Closest points
};

// Class for all the parameters for hooke's law
class hook_param{
    public:
        double timestep, spring_const, rest_l, mass;
};

vector <double> hookes(double dist, double velocity, hook_param params);
void test();
vector <point> create_sphere(double radius, double rest_length,
                             double init_v_x, double init_v_y,
                             double init_v_z);
vector <point> simulate(vector <point> curr_sphere, hook_param params);

/*----------------------------------------------------------------------------//
* MAIN
*-----------------------------------------------------------------------------*/
int main(){
    test();

    double radius = 5.0;
    double rest_length = 0.5 * radius;
    double init_v_x, init_v_z, init_v_y;
    vector <point> points;

    init_v_x = 0; init_v_y = 0; init_v_z = 0;
    points = create_sphere(radius, rest_length, init_v_x, init_v_y, init_v_z);

}

/*----------------------------------------------------------------------------//
* SUBROUTINES / FUNCTIONS
*-----------------------------------------------------------------------------*/

// Simple solver for Hooke's law. I could use RK4, but this'll do for now.
vector<double> hookes(double dist, double velocity, hook_param params){

    vector<double> both;

    dist += (velocity * params.timestep)
            + params.timestep * params.timestep
            *(0.5 * params.spring_const * (params.rest_l - dist) / params.mass);
    velocity += params.timestep*(params.spring_const *
                                (params.rest_l - dist) / params.mass);

    both.push_back(dist); both.push_back(velocity);

    return both;
}

// Test for Hooke's function... and potentially RK4 in a bit.
void test(){

    hook_param params;
    params.timestep     = 0.0001;
    params.mass         = 0.001;
    params.spring_const = 1;
    params.rest_l       = 10;
    vector<double> solution;
    double distance = 9.0,velocity = 0;

    solution.push_back(distance);
    solution.push_back(velocity);
    for (int i = 0; i < 100; i++){
        solution = hookes(solution[0],solution[1],params);
        cout << solution[0] << '\t' << solution[1] << endl;

    }
}

// Populate sphere of points. Brutish, sure... but it'll do.
// Note: make reat_length a multiple of radius. That makes things easier.
// Also: Checked
vector <point> create_sphere(double radius, double rest_length,
                             double init_v_x, double init_v_y,
                             double init_v_z){

    // The idea here is simple. We will start at the corner of our sphere and
    // create points in x, then y, then z that are each rest_length atart from
    // one another. Whenever any of these parameters are
    // outside of the radius of our sphere, we move to the next parameter.
    // The end result should be a vector of points, moving at our initial vel.

    vector<point> points;                               // All points
    point dummy;                                        // Dummy point
    int count = 0;                                      // Just a count

    cout << "Populating sphere..." << endl;

    for (double ix = -radius; ix <= (radius); ix = ix+ rest_length){
        for (double iy = -radius; iy <= (radius); iy = iy + rest_length){
            for (double iz = -radius; iz <= (radius); iz = iz + rest_length){

                if (((ix * ix) + (iy * iy) + (iz * iz)) <= radius*radius){
                    dummy.step_num = count;
                    dummy.x = ix;
                    dummy.y = iy;
                    dummy.z = iz;
                    dummy.v_x = init_v_x;
                    dummy.v_y = init_v_y;
                    dummy.v_z = init_v_z;
                    points.push_back(dummy);
                    count++;
                }

            }

        }

    }

    // Now I need to figure out which ones are closest to each other.
    // Note: if I want to use this code later, I can easily break this f(x)
    //       in half.

    cout << "Finding closest particles..." << endl;

    double x, y, z;

    for (int i = 0; i < points.size(); i++){
        x = points[i].x;
        y = points[i].y;
        z = points[i].z;

        // Let's find the maximum count number (fcount)
        double count_up, count_down;
        int fcount;

        count_up = radius*radius - (x+rest_length)*(x+rest_length);
        count_down = radius*radius - (x-rest_length)*(x-rest_length);

        if (count_down > count_up){
            fcount = count_down;
        }
        else{
            fcount = count_up;
        }

        for (int ii = 0; ii < fcount; ii++){

            // UP
            if ( points[i].z == points[i + ii].z){
                points[i].next.up = points[i+ii].z;
            }

            // RIGHT
            if ( points[i].y == points[i + ii].y){
                points[i].next.right = points[i+ii].y;
            }

            // FORW
            if ( points[i].x == points[i + ii].x){
                points[i].next.forw = points[i+ii].x;
            }

            if ( i >= ii){

                // DOWN
                if ( points[i].z == points[i - ii].z){
                    points[i].next.down = points[i-ii].z;
                }

                // LEFT
                if ( points[i].y == points[i - ii].y){
                    points[i].next.left = points[i+ii].y;
                }

                // BACK
                if ( points[i].x == points[i - ii].x){
                    points[i].next.back = points[i+ii].x;
                }

            }

        }

    }
    return points;
}

// Now I need to prepare each point so that it reads into my Hooke's law f(x).
vector <point> simulate(vector <point> curr_sphere, hook_param params){

    int dir;
    double del_x, del_y, del_z, theta_xy, theta_zy, del_tot;

    // I need to get the velocities from each component in the spring direction
    double del_vx, del_vy, del_vz, vel_fx, vel_fy, vel_fz, vel_tot;

    vector <double> solution;

    solution.push_back(1.000);     solution.push_back(1.000);

    for (int i = 0; i < curr_sphere.size(); i++){
        for (int ii = 0; ii < 6; ii++){
            if (ii = 0){dir = curr_sphere[i].next.up;}
            if (ii = 1){dir = curr_sphere[i].next.down;}
            if (ii = 2){dir = curr_sphere[i].next.left;}
            if (ii = 3){dir = curr_sphere[i].next.right;}
            if (ii = 4){dir = curr_sphere[i].next.forw;}
            if (ii = 5){dir = curr_sphere[i].next.back;}

            del_x = curr_sphere[i].x - curr_sphere[dir].x;
            del_y = curr_sphere[i].y - curr_sphere[dir].y;
            del_z = curr_sphere[i].z - curr_sphere[dir].z;
            theta_xy = atan( del_y / del_x);
            theta_zy = atan( del_y / del_z);

            del_tot = del_x*del_x + del_y*del_y + del_z*del_z;

            del_vx = curr_sphere[i].v_x - curr_sphere[dir].v_x;
            del_vy = curr_sphere[i].v_y - curr_sphere[dir].v_y;
            del_vz = curr_sphere[i].v_z - curr_sphere[dir].v_z;

            vel_fz = del_vz / cos(theta_zy);
            vel_fy = del_vy / sin(theta_xy);
            vel_fx = del_vx / cos(theta_xy);

            vel_tot = vel_fx + vel_fy + vel_fz;

            solution[0] = del_tot;     solution[1] = vel_tot;

            solution = hookes(solution[0], solution[1], params);

            del_x = solution[0] * cos(theta_xy);
            del_y = solution[0] * sin(theta_xy);
            del_z = solution[0] * cos(theta_zy);
            del_vx = solution[1] * cos(theta_xy);
            del_vy = solution[1] * sin(theta_xy);
            del_vz = solution[1] * cos(theta_zy);

            curr_sphere[i].x += (0.5 * del_x);
            curr_sphere[i].y += (0.5 * del_y);
            curr_sphere[i].z += (0.5 * del_z);
            curr_sphere[dir].x += (0.5 * del_x);
            curr_sphere[dir].y += (0.5 * del_y);
            curr_sphere[dir].z += (0.5 * del_z);

            curr_sphere[i].v_x += (0.5 * del_vx);
            curr_sphere[i].v_y += (0.5 * del_vy);
            curr_sphere[i].v_z += (0.5 * del_vz);
            curr_sphere[dir].v_x += (0.5 * del_vx);
            curr_sphere[dir].v_y += (0.5 * del_vy);
            curr_sphere[dir].v_z += (0.5 * del_vz);

        }
    }
}
<commit_msg>well, it runs now... I still need to check the outputs and such.<commit_after>/*-------------simple.cpp-----------------------------------------------------//
*
* Purpose: This file is a simple example of how we can simulate the defomation
*          of balls with a newton-solver algorithm. I have referred to RK4 a
*          few tiems and may implement it if this ends up becoming too slow in
*          the future, but I think it should be fine.
*
*-----------------------------------------------------------------------------*/

#include <iostream>
#include <vector>
#include <cmath>

/*----------------------------------------------------------------------------//
* STRUCTURES AND FUNCTIONS
*-----------------------------------------------------------------------------*/
using namespace std;

// Structure to point to the closest points in each direction
// I might actually use pointer later, but not for now.
struct closest{
    int up,down,forw,back,left,right;
};

// Class to hold all values of particles.
class point{
    public:
        int step_num;                                  // Time-step number.
        double x, y, z;                                // Position in x, y, z
        double v_x, v_y, v_z;                          // Velocity in x, y, z
        closest next;                                  // Closest points
};

// Class for all the parameters for hooke's law
class hook_param{
    public:
        double timestep, spring_const, rest_l, mass;
};

vector <double> hookes(double dist, double velocity, hook_param params);
void test(hook_param params);
vector <point> create_sphere(double radius, double rest_length,
                             double init_v_x, double init_v_y,
                             double init_v_z);
vector <point> simulate(vector <point> curr_sphere, hook_param params);

/*----------------------------------------------------------------------------//
* MAIN
*-----------------------------------------------------------------------------*/
int main(){

    hook_param params;
    params.timestep     = 0.0001;
    params.mass         = 0.001;
    params.spring_const = 1;
    params.rest_l       = 10;

    test(params);

    double radius = 5.0;
    double rest_length = 0.5 * radius;
    double init_v_x, init_v_z, init_v_y;
    vector <point> points;

    init_v_x = 0; init_v_y = 0; init_v_z = 0;
    points = create_sphere(radius, rest_length, init_v_x, init_v_y, init_v_z);
    points = simulate( points, params);

}

/*----------------------------------------------------------------------------//
* SUBROUTINES / FUNCTIONS
*-----------------------------------------------------------------------------*/

// Simple solver for Hooke's law. I could use RK4, but this'll do for now.
vector<double> hookes(double dist, double velocity, hook_param params){

    vector<double> both;

    dist += (velocity * params.timestep)
            + params.timestep * params.timestep
            *(0.5 * params.spring_const * (params.rest_l - dist) / params.mass);
    velocity += params.timestep*(params.spring_const *
                                (params.rest_l - dist) / params.mass);

    both.push_back(dist); both.push_back(velocity);

    return both;
}

// Test for Hooke's function... and potentially RK4 in a bit.
void test(hook_param params){

    vector<double> solution;
    double distance = 9.0,velocity = 0;

    solution.push_back(distance);
    solution.push_back(velocity);
    for (int i = 0; i < 100; i++){
        solution = hookes(solution[0],solution[1],params);
        cout << solution[0] << '\t' << solution[1] << endl;

    }
}

// Populate sphere of points. Brutish, sure... but it'll do.
// Note: make reat_length a multiple of radius. That makes things easier.
// Also: Checked
vector <point> create_sphere(double radius, double rest_length,
                             double init_v_x, double init_v_y,
                             double init_v_z){

    // The idea here is simple. We will start at the corner of our sphere and
    // create points in x, then y, then z that are each rest_length atart from
    // one another. Whenever any of these parameters are
    // outside of the radius of our sphere, we move to the next parameter.
    // The end result should be a vector of points, moving at our initial vel.

    vector<point> points;                               // All points
    point dummy;                                        // Dummy point
    int count = 0;                                      // Just a count

    cout << "Populating sphere..." << endl;

    for (double ix = -radius; ix <= (radius); ix = ix+ rest_length){
        for (double iy = -radius; iy <= (radius); iy = iy + rest_length){
            for (double iz = -radius; iz <= (radius); iz = iz + rest_length){

                if (((ix * ix) + (iy * iy) + (iz * iz)) <= radius*radius){
                    dummy.step_num = count;
                    dummy.x = ix;
                    dummy.y = iy;
                    dummy.z = iz;
                    dummy.v_x = init_v_x;
                    dummy.v_y = init_v_y;
                    dummy.v_z = init_v_z;
                    points.push_back(dummy);
                    count++;
                }

            }

        }

    }

    // Now I need to figure out which ones are closest to each other.
    // Note: if I want to use this code later, I can easily break this f(x)
    //       in half.

    cout << "Finding closest particles..." << endl;

    double x, y, z;

    for (int i = 0; i < points.size(); i++){
        x = points[i].x;
        y = points[i].y;
        z = points[i].z;

        // Let's find the maximum count number (fcount)
        double count_up, count_down;
        int fcount;

        count_up = radius*radius - (x+rest_length)*(x+rest_length);
        count_down = radius*radius - (x-rest_length)*(x-rest_length);

        if (count_down > count_up){
            fcount = count_down;
        }
        else{
            fcount = count_up;
        }

        for (int ii = 0; ii < fcount; ii++){

            // UP
            if ( points[i].z == points[i + ii].z){
                points[i].next.up = points[i+ii].z;
            }

            // RIGHT
            if ( points[i].y == points[i + ii].y){
                points[i].next.right = points[i+ii].y;
            }

            // FORW
            if ( points[i].x == points[i + ii].x){
                points[i].next.forw = points[i+ii].x;
            }

            if ( i >= ii){

                // DOWN
                if ( points[i].z == points[i - ii].z){
                    points[i].next.down = points[i-ii].z;
                }

                // LEFT
                if ( points[i].y == points[i - ii].y){
                    points[i].next.left = points[i+ii].y;
                }

                // BACK
                if ( points[i].x == points[i - ii].x){
                    points[i].next.back = points[i+ii].x;
                }

            }

        }

    }
    return points;
}

// Now I need to prepare each point so that it reads into my Hooke's law f(x).
vector <point> simulate(vector <point> curr_sphere, hook_param params){

    int dir;
    double del_x, del_y, del_z, theta_xy, theta_zy, del_tot;

    // I need to get the velocities from each component in the spring direction
    double del_vx, del_vy, del_vz, vel_fx, vel_fy, vel_fz, vel_tot;

    vector <double> solution;

    solution.push_back(1.000);     solution.push_back(1.000);

    for (int i = 0; i < curr_sphere.size(); i++){
        for (int ii = 0; ii < 6; ii++){
            if (ii = 0){dir = curr_sphere[i].next.up;}
            if (ii = 1){dir = curr_sphere[i].next.down;}
            if (ii = 2){dir = curr_sphere[i].next.left;}
            if (ii = 3){dir = curr_sphere[i].next.right;}
            if (ii = 4){dir = curr_sphere[i].next.forw;}
            if (ii = 5){dir = curr_sphere[i].next.back;}

            del_x = curr_sphere[i].x - curr_sphere[dir].x;
            del_y = curr_sphere[i].y - curr_sphere[dir].y;
            del_z = curr_sphere[i].z - curr_sphere[dir].z;
            theta_xy = atan( del_y / del_x);
            theta_zy = atan( del_y / del_z);

            del_tot = del_x*del_x + del_y*del_y + del_z*del_z;

            del_vx = curr_sphere[i].v_x - curr_sphere[dir].v_x;
            del_vy = curr_sphere[i].v_y - curr_sphere[dir].v_y;
            del_vz = curr_sphere[i].v_z - curr_sphere[dir].v_z;

            vel_fz = del_vz / cos(theta_zy);
            vel_fy = del_vy / sin(theta_xy);
            vel_fx = del_vx / cos(theta_xy);

            vel_tot = vel_fx + vel_fy + vel_fz;

            solution[0] = del_tot;     solution[1] = vel_tot;

            solution = hookes(solution[0], solution[1], params);

            del_x = solution[0] * cos(theta_xy);
            del_y = solution[0] * sin(theta_xy);
            del_z = solution[0] * cos(theta_zy);
            del_vx = solution[1] * cos(theta_xy);
            del_vy = solution[1] * sin(theta_xy);
            del_vz = solution[1] * cos(theta_zy);

            curr_sphere[i].x += (0.5 * del_x);
            curr_sphere[i].y += (0.5 * del_y);
            curr_sphere[i].z += (0.5 * del_z);
            curr_sphere[dir].x += (0.5 * del_x);
            curr_sphere[dir].y += (0.5 * del_y);
            curr_sphere[dir].z += (0.5 * del_z);

            curr_sphere[i].v_x += (0.5 * del_vx);
            curr_sphere[i].v_y += (0.5 * del_vy);
            curr_sphere[i].v_z += (0.5 * del_vz);
            curr_sphere[dir].v_x += (0.5 * del_vx);
            curr_sphere[dir].v_y += (0.5 * del_vy);
            curr_sphere[dir].v_z += (0.5 * del_vz);

        }

        curr_sphere[i].x += params.timestep * curr_sphere[i].v_x;
        curr_sphere[i].y += params.timestep * curr_sphere[i].v_y;
        curr_sphere[i].z += params.timestep * curr_sphere[i].v_z;

    }

return curr_sphere;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 */

// CLASS HEADER
#include "vertical-layout-impl.h"

// INTERNAL INCLUDES
#include "vertical-layout.h"

namespace Dali
{

namespace Toolkit
{

namespace Internal
{

Toolkit::VerticalLayout VerticalLayout::New()
{
  // Create the implementation, temporarily owned by this handle on stack
  IntrusivePtr< VerticalLayout > impl = new VerticalLayout();

  // Pass ownership to CustomActor handle
  Toolkit::VerticalLayout handle( *impl );

  // Second-phase init of the implementation
  // This can only be done after the CustomActor connection has been made...
  impl->Initialize();

  return handle;
}

VerticalLayout::VerticalLayout()
: Control( ControlBehaviour( CONTROL_BEHAVIOUR_NONE ) )
{
}

VerticalLayout::~VerticalLayout()
{
}

void VerticalLayout::OnInitialize()
{
}

Vector3 VerticalLayout::GetNaturalSize()
{
  Vector3 size = Vector3::ZERO;

  CustomActor self = Self();
  for( unsigned int index = 0u, count = self.GetChildCount(); index < count; ++index )
  {
    Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( self.GetChildAt( index ) );

    if( label )
    {
      Vector3 labelSize = label.GetNaturalSize();

      size.width = ( labelSize.width > size.width ) ? labelSize.width : size.width;
      size.height += labelSize.height + 50.0f/*FIXME*/;
    }
  }

  return size;
}

float VerticalLayout::GetHeightForWidth( float width )
{
  float height = 0.f;

  CustomActor self = Self();
  for( unsigned int index = 0u, count = self.GetChildCount(); index < count; ++index )
  {
    Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( self.GetChildAt( index ) );

    if( label )
    {
      height += label.GetHeightForWidth( width ) + 50.0f/*FIXME*/;
    }
  }

  return height;
}

float VerticalLayout::GetWidthForHeight( float height )
{
  return 0.f;
}

void VerticalLayout::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
{
}

void VerticalLayout::OnRelayout( const Vector2& size, ActorSizeContainer& container )
{
  CustomActor self = Self();

  Vector3 position;
  for( unsigned int index = 0u, count = self.GetChildCount(); index < count; ++index )
  {
    Size childSize = size;
    Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( self.GetChildAt( index ) );

    if( label )
    {
      label.SetPosition( position );

      childSize.height = label.GetHeightForWidth( size.width );
      position.height += childSize.height + 50.0f/*FIXME*/;

      label.SetSize( childSize );
    }

    container.push_back( ActorSizePair( label, childSize ) );
  }
}

void VerticalLayout::AddLabel( Toolkit::TextLabel label )
{
  Self().Add( label );

  RelayoutRequest();
}

} // namespace Internal

} // namespace Toolkit

} // namespace Dali
<commit_msg>Revert "Work-around regression with vertical layout"<commit_after>/*
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 */

// CLASS HEADER
#include "vertical-layout-impl.h"

// INTERNAL INCLUDES
#include "vertical-layout.h"

namespace Dali
{

namespace Toolkit
{

namespace Internal
{

Toolkit::VerticalLayout VerticalLayout::New()
{
  // Create the implementation, temporarily owned by this handle on stack
  IntrusivePtr< VerticalLayout > impl = new VerticalLayout();

  // Pass ownership to CustomActor handle
  Toolkit::VerticalLayout handle( *impl );

  // Second-phase init of the implementation
  // This can only be done after the CustomActor connection has been made...
  impl->Initialize();

  return handle;
}

VerticalLayout::VerticalLayout()
: Control( ControlBehaviour( CONTROL_BEHAVIOUR_NONE ) )
{
}

VerticalLayout::~VerticalLayout()
{
}

void VerticalLayout::OnInitialize()
{
}

Vector3 VerticalLayout::GetNaturalSize()
{
  Vector3 size = Vector3::ZERO;

  CustomActor self = Self();
  for( unsigned int index = 0u, count = self.GetChildCount(); index < count; ++index )
  {
    Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( self.GetChildAt( index ) );

    if( label )
    {
      Vector3 labelSize = label.GetNaturalSize();

      size.width = ( labelSize.width > size.width ) ? labelSize.width : size.width;
      size.height += labelSize.height;
    }
  }

  return size;
}

float VerticalLayout::GetHeightForWidth( float width )
{
  float height = 0.f;

  CustomActor self = Self();
  for( unsigned int index = 0u, count = self.GetChildCount(); index < count; ++index )
  {
    Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( self.GetChildAt( index ) );

    if( label )
    {
      height += label.GetHeightForWidth( width );
    }
  }

  return height;
}

float VerticalLayout::GetWidthForHeight( float height )
{
  return 0.f;
}

void VerticalLayout::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
{
}

void VerticalLayout::OnRelayout( const Vector2& size, ActorSizeContainer& container )
{
  CustomActor self = Self();

  Vector3 position;
  for( unsigned int index = 0u, count = self.GetChildCount(); index < count; ++index )
  {
    Size childSize = size;
    Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( self.GetChildAt( index ) );

    if( label )
    {
      label.SetPosition( position );

      childSize.height = label.GetHeightForWidth( size.width );
      position.height += childSize.height;

      label.SetSize( childSize );
    }

    container.push_back( ActorSizePair( label, childSize ) );
  }
}

void VerticalLayout::AddLabel( Toolkit::TextLabel label )
{
  Self().Add( label );

  RelayoutRequest();
}

} // namespace Internal

} // namespace Toolkit

} // namespace Dali
<|endoftext|>


<commit_before>#include "CppSimulation.hpp"
#include "CppSystem.hpp"
#include "StoreHandler.hpp"

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include <sstream>
#include <boost/algorithm/string/replace.hpp>

#include <iostream>
#include <windows.h>

namespace pt = boost::property_tree;

typedef pysim::CppSystem*(__cdecl *funcpt)(const char* name);

struct systeminfo {
    std::string name;
    std::string type;
    std::string module;
    std::vector<std::pair<std::string, std::double_t>> inputs;
    std::vector<std::string> stores;
};

int main(int argc, char *argv[]) {
    using std::string;
    using std::pair;

    string simfilename;
    string modulerootpath;
    if (argc < 3) {
        std::cout << "warning: using default filename and modulepath" << std::endl;
        simfilename = "simplesim.json";
        modulerootpath = "C:\\dev\\pysims\\pysim\\";
    } else {
        simfilename = string(argv[1]);
        modulerootpath = string(argv[2]);
    }

    pt::ptree root;
    pt::read_json(simfilename, root);

    std::vector<systeminfo> system_infos;

    for (pt::ptree::value_type &json_system : root.get_child("systems")) {
        systeminfo sys;
        sys.name = json_system.first;
        sys.type = json_system.second.get_child("type").data();
        sys.module = json_system.second.get_child("module").data();
        for (pt::ptree::value_type & json_input : json_system.second.get_child("inputs")) {
            string key = json_input.first;
            string value(json_input.second.data());
            sys.inputs.push_back(std::make_pair(key, std::stod(value)));
        }
        for (pt::ptree::value_type & json_store : json_system.second.get_child("stores")) {
            sys.stores.push_back(json_store.second.data());
        }
        system_infos.push_back(sys);
    }

    std::map<string, funcpt> factorymap;
    for (systeminfo &sys : system_infos) {
        if (factorymap.count(sys.module) == 0) {
            std::stringstream ss;
            ss << modulerootpath;
            string module(sys.module);
            boost::algorithm::replace_all(module, ".", "\\");
            ss << module << ".cp35-win32.pyd";
            HINSTANCE hGetProcIDDLL = LoadLibrary(ss.str().c_str());
            if (!hGetProcIDDLL) {
                int errorcode = GetLastError();
                std::cout << "could not load the dynamic library: " << errorcode << std::endl;
                return 1;
            }
            funcpt funci = (funcpt)GetProcAddress(hGetProcIDDLL, "getCppSystem");
            if (!funci) {
                std::cout << "could not locate the function" << std::endl;
                return 1;
            }
            factorymap[sys.module] = funci;
        }
    }

    pysim::Simulation sim;
    std::map<string, pysim::CppSystem*> systems;

    for (systeminfo& sys_info : system_infos) {
        pysim::CppSystem* sys = factorymap[sys_info.module](sys_info.type.c_str());
        for (std::string name: sys_info.stores){
            //sys->store(name.c_str());
        }
        systems[sys_info.name] = sys;
        sim.addSystem(sys);
    }

    sim.simulate(200, 0.1,"rk4",0.1,0.1,false);
    std::vector<double> v;
    pysim::CppSystem* sys = systems["vanderpol"];
    v = sys->getStoreHandlerP()->getStoreVector("x");
    std::cout << v.at(20) << std::endl;

}
<commit_msg>temporary name fix<commit_after>#include "CppSimulation.hpp"
#include "CppSystem.hpp"
#include "StoreHandler.hpp"

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include <sstream>
#include <boost/algorithm/string/replace.hpp>

#include <iostream>
#include <windows.h>

namespace pt = boost::property_tree;

typedef pysim::CppSystem*(__cdecl *funcpt)(const char* name);

struct systeminfo {
    std::string name;
    std::string type;
    std::string module;
    std::vector<std::pair<std::string, std::double_t>> inputs;
    std::vector<std::string> stores;
};

int main(int argc, char *argv[]) {
    using std::string;
    using std::pair;

    string simfilename;
    string modulerootpath;
    if (argc < 3) {
        std::cout << "warning: using default filename and modulepath" << std::endl;
        simfilename = "simplesim.json";
        modulerootpath = "C:\\dev\\pysims\\pysim\\";
    } else {
        simfilename = string(argv[1]);
        modulerootpath = string(argv[2]);
    }

    pt::ptree root;
    pt::read_json(simfilename, root);

    std::vector<systeminfo> system_infos;

    for (pt::ptree::value_type &json_system : root.get_child("systems")) {
        systeminfo sys;
        sys.name = json_system.first;
        sys.type = json_system.second.get_child("type").data();
        sys.module = json_system.second.get_child("module").data();
        for (pt::ptree::value_type & json_input : json_system.second.get_child("inputs")) {
            string key = json_input.first;
            string value(json_input.second.data());
            sys.inputs.push_back(std::make_pair(key, std::stod(value)));
        }
        for (pt::ptree::value_type & json_store : json_system.second.get_child("stores")) {
            sys.stores.push_back(json_store.second.data());
        }
        system_infos.push_back(sys);
    }

    std::map<string, funcpt> factorymap;
    for (systeminfo &sys : system_infos) {
        if (factorymap.count(sys.module) == 0) {
            std::stringstream ss;
            ss << modulerootpath;
            string module(sys.module);
            boost::algorithm::replace_all(module, ".", "\\");
            ss << module << ".cp35-win32.pyd";
            HINSTANCE hGetProcIDDLL = LoadLibrary(ss.str().c_str());
            if (!hGetProcIDDLL) {
                int errorcode = GetLastError();
                std::cout << "could not load the dynamic library: " << errorcode << std::endl;
                return 1;
            }
            funcpt funci = (funcpt)GetProcAddress(hGetProcIDDLL, "getCppSystem");
            if (!funci) {
                std::cout << "could not locate the function" << std::endl;
                return 1;
            }
            factorymap[sys.module] = funci;
        }
    }

    pysim::Simulation sim;
    std::map<string, pysim::CppSystem*> systems;

    for (systeminfo& sys_info : system_infos) {
        pysim::CppSystem* sys = factorymap[sys_info.module](sys_info.type.c_str());
        for (std::string name: sys_info.stores){
            sys->store("x");
        }
        systems[sys_info.name] = sys;
        sim.addSystem(sys);
    }

    sim.simulate(200, 0.1,"rk4",0.1,0.1,false);
    std::vector<double> v;
    pysim::CppSystem* sys = systems["vanderpol"];
    v = sys->getStoreHandlerP()->getStoreVector("x");
    std::cout << v.at(20) << std::endl;

}
<|endoftext|>


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

#ifdef WNT
#include    <tools/prewin.h>
#include "winbase.h"
#include    <tools/postwin.h>
#endif

#ifndef _ERRCODE_HXX //autogen
#include <tools/errcode.hxx>
#endif
#ifndef _VOS_PROCESS_HXX_
#include <vos/process.hxx>
#endif
#ifndef _SBXCORE_HXX
#include <sbxcore.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif

#ifndef _BASIC_TTRESHLP_HXX
#include "ttstrhlp.hxx"
#endif

//#ifndef _BYTE_STRING_LIST
//DECLARE_LIST( ByteStringList, ByteString * );
//#define _BYTE_STRING_LIST
//#endif

#include "process.hxx"

// Konstruktor fr den Process
Process::Process()
: bWasGPF( FALSE )
, pArgumentList( NULL )
, pEnvList( NULL )
, pProcess( NULL )
, bHasBeenStarted( FALSE )
{
}

// Destruktor
Process::~Process()
{
//    delete pArgumentList;
//    delete pEnvList;
    delete pProcess;
}

BOOL Process::ImplIsRunning()
{
    if ( pProcess && bHasBeenStarted )
    {
        NAMESPACE_VOS(OProcess::TProcessInfo) aProcessInfo;
        pProcess->getInfo( NAMESPACE_VOS(OProcess::TData_ExitCode), &aProcessInfo );
        if ( !(aProcessInfo.Fields & NAMESPACE_VOS(OProcess::TData_ExitCode)) )
            return TRUE;
        else
            return FALSE;
    }
    else
        return FALSE;
}

long Process::ImplGetExitCode()
{
    if ( pProcess )
    {
        NAMESPACE_VOS(OProcess::TProcessInfo) aProcessInfo;
        pProcess->getInfo( NAMESPACE_VOS(OProcess::TData_ExitCode), &aProcessInfo );
        if ( !(aProcessInfo.Fields & NAMESPACE_VOS(OProcess::TData_ExitCode)) )
            SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
        return aProcessInfo.Code;
    }
    else
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
        return 0;
}

////////////////////////////////////////////////////////////////////////////

// Die Methoden:
void Process::SetImage( const String &aAppPath, const String &aAppParams, const Environment *pEnv )
{ // Imagedatei des Executables
    if ( pProcess && ImplIsRunning() )
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
    else
    {
        delete pArgumentList; pArgumentList = NULL;
        delete pEnvList; pEnvList = NULL;
        delete pProcess; pProcess = NULL;

        xub_StrLen i, nCount = aAppParams.GetQuotedTokenCount( CUniString("\"\"" ), ' ' );
        ::rtl::OUString *pParamList = new ::rtl::OUString[nCount];

        xub_StrLen nParamCount = 0;
        for ( i = 0 ; i < nCount ; i++ )
        {
            ::rtl::OUString aTemp = ::rtl::OUString(aAppParams.GetQuotedToken( i, CUniString("\"\"''" ), ' ' ));
            if ( aTemp.getLength() )
            {
                pParamList[nParamCount] = aTemp;
                nParamCount++;
            }
        }
        pArgumentList = new NAMESPACE_VOS(OArgumentList)( pParamList, nCount );

        ::rtl::OUString *pEnvArray = NULL;
        if ( pEnv )
        {

            nCount = pEnv->size();
            pEnvArray = new ::rtl::OUString[nCount];

            xub_StrLen nEnvCount = 0;
            Environment::const_iterator aIter = pEnv->begin();
            while ( aIter != pEnv->end() )
            {
                ::rtl::OUString aTemp = ::rtl::OUString( (*aIter).first );
                aTemp += ::rtl::OUString::createFromAscii( "=" );
                aTemp += ::rtl::OUString( (*aIter).second );
                pEnvArray[nEnvCount] = aTemp;
                nEnvCount++;
                aIter++;
            }
            pEnvList = new NAMESPACE_VOS(OEnvironment)( pEnvArray, nEnvCount );
        }

        ::rtl::OUString aNormalizedAppPath;
        osl::FileBase::getFileURLFromSystemPath( ::rtl::OUString(aAppPath), aNormalizedAppPath );
        pProcess = new NAMESPACE_VOS(OProcess)( aNormalizedAppPath );
        bHasBeenStarted = FALSE;

        delete [] pParamList;
        delete [] pEnvArray;
    }
}

BOOL Process::Start()
{ // Programm wird gestartet
    BOOL bSuccess=FALSE;
    if ( pProcess && !ImplIsRunning() )
    {
        bWasGPF = FALSE;
#ifdef WNT
//      sal_uInt32 nErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT | SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
        sal_uInt32 nErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX);
        try
        {
#endif
            if ( pEnvList )
            {
                bSuccess = pProcess->execute( (NAMESPACE_VOS(OProcess)::TProcessOption)
                            ( NAMESPACE_VOS(OProcess)::TOption_SearchPath
                            /*| NAMESPACE_VOS(OProcess)::TOption_Detached*/
                            /*| NAMESPACE_VOS(OProcess)::TOption_Wait*/ ),
                            *pArgumentList,
                            *pEnvList ) == NAMESPACE_VOS(OProcess)::E_None;
            }
            else
            {
                bSuccess = pProcess->execute( (NAMESPACE_VOS(OProcess)::TProcessOption)
                            ( NAMESPACE_VOS(OProcess)::TOption_SearchPath
                            /*| NAMESPACE_VOS(OProcess)::TOption_Detached*/
                            /*| NAMESPACE_VOS(OProcess)::TOption_Wait*/ ),
                            *pArgumentList ) == NAMESPACE_VOS(OProcess)::E_None;
            }
#ifdef WNT
        }
        catch( ... )
        {
            bWasGPF = TRUE;
        }
        nErrorMode = SetErrorMode(nErrorMode);
#endif
        bHasBeenStarted = bSuccess;
    }
    else
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
    return bSuccess;
}

ULONG Process::GetExitCode()
{ // ExitCode des Programms(nachdem es beendet ist)
    return ImplGetExitCode();
}

BOOL Process::IsRunning()
{ // Programm luft noch
    return ImplIsRunning();
}

BOOL Process::WasGPF()
{ // Programm mit GPF o.. abgebrochen
#ifdef WNT
    return ImplGetExitCode() == 3221225477;
#else
    return bWasGPF;
#endif
}

BOOL Process::Terminate()
{
    if ( ImplIsRunning() )
        return pProcess->terminate() == vos::OProcess::E_None;
    return TRUE;
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.10.34); FILE MERGED 2005/09/05 14:35:56 rt 1.10.34.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: process.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 21:18:34 $
 *
 *  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
 *
 ************************************************************************/

#ifdef WNT
#include    <tools/prewin.h>
#include "winbase.h"
#include    <tools/postwin.h>
#endif

#ifndef _ERRCODE_HXX //autogen
#include <tools/errcode.hxx>
#endif
#ifndef _VOS_PROCESS_HXX_
#include <vos/process.hxx>
#endif
#ifndef _SBXCORE_HXX
#include <sbxcore.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif

#ifndef _BASIC_TTRESHLP_HXX
#include "ttstrhlp.hxx"
#endif

//#ifndef _BYTE_STRING_LIST
//DECLARE_LIST( ByteStringList, ByteString * );
//#define _BYTE_STRING_LIST
//#endif

#include "process.hxx"

// Konstruktor fr den Process
Process::Process()
: bWasGPF( FALSE )
, pArgumentList( NULL )
, pEnvList( NULL )
, pProcess( NULL )
, bHasBeenStarted( FALSE )
{
}

// Destruktor
Process::~Process()
{
//    delete pArgumentList;
//    delete pEnvList;
    delete pProcess;
}

BOOL Process::ImplIsRunning()
{
    if ( pProcess && bHasBeenStarted )
    {
        NAMESPACE_VOS(OProcess::TProcessInfo) aProcessInfo;
        pProcess->getInfo( NAMESPACE_VOS(OProcess::TData_ExitCode), &aProcessInfo );
        if ( !(aProcessInfo.Fields & NAMESPACE_VOS(OProcess::TData_ExitCode)) )
            return TRUE;
        else
            return FALSE;
    }
    else
        return FALSE;
}

long Process::ImplGetExitCode()
{
    if ( pProcess )
    {
        NAMESPACE_VOS(OProcess::TProcessInfo) aProcessInfo;
        pProcess->getInfo( NAMESPACE_VOS(OProcess::TData_ExitCode), &aProcessInfo );
        if ( !(aProcessInfo.Fields & NAMESPACE_VOS(OProcess::TData_ExitCode)) )
            SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
        return aProcessInfo.Code;
    }
    else
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
        return 0;
}

////////////////////////////////////////////////////////////////////////////

// Die Methoden:
void Process::SetImage( const String &aAppPath, const String &aAppParams, const Environment *pEnv )
{ // Imagedatei des Executables
    if ( pProcess && ImplIsRunning() )
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
    else
    {
        delete pArgumentList; pArgumentList = NULL;
        delete pEnvList; pEnvList = NULL;
        delete pProcess; pProcess = NULL;

        xub_StrLen i, nCount = aAppParams.GetQuotedTokenCount( CUniString("\"\"" ), ' ' );
        ::rtl::OUString *pParamList = new ::rtl::OUString[nCount];

        xub_StrLen nParamCount = 0;
        for ( i = 0 ; i < nCount ; i++ )
        {
            ::rtl::OUString aTemp = ::rtl::OUString(aAppParams.GetQuotedToken( i, CUniString("\"\"''" ), ' ' ));
            if ( aTemp.getLength() )
            {
                pParamList[nParamCount] = aTemp;
                nParamCount++;
            }
        }
        pArgumentList = new NAMESPACE_VOS(OArgumentList)( pParamList, nCount );

        ::rtl::OUString *pEnvArray = NULL;
        if ( pEnv )
        {

            nCount = pEnv->size();
            pEnvArray = new ::rtl::OUString[nCount];

            xub_StrLen nEnvCount = 0;
            Environment::const_iterator aIter = pEnv->begin();
            while ( aIter != pEnv->end() )
            {
                ::rtl::OUString aTemp = ::rtl::OUString( (*aIter).first );
                aTemp += ::rtl::OUString::createFromAscii( "=" );
                aTemp += ::rtl::OUString( (*aIter).second );
                pEnvArray[nEnvCount] = aTemp;
                nEnvCount++;
                aIter++;
            }
            pEnvList = new NAMESPACE_VOS(OEnvironment)( pEnvArray, nEnvCount );
        }

        ::rtl::OUString aNormalizedAppPath;
        osl::FileBase::getFileURLFromSystemPath( ::rtl::OUString(aAppPath), aNormalizedAppPath );
        pProcess = new NAMESPACE_VOS(OProcess)( aNormalizedAppPath );
        bHasBeenStarted = FALSE;

        delete [] pParamList;
        delete [] pEnvArray;
    }
}

BOOL Process::Start()
{ // Programm wird gestartet
    BOOL bSuccess=FALSE;
    if ( pProcess && !ImplIsRunning() )
    {
        bWasGPF = FALSE;
#ifdef WNT
//      sal_uInt32 nErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT | SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
        sal_uInt32 nErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX);
        try
        {
#endif
            if ( pEnvList )
            {
                bSuccess = pProcess->execute( (NAMESPACE_VOS(OProcess)::TProcessOption)
                            ( NAMESPACE_VOS(OProcess)::TOption_SearchPath
                            /*| NAMESPACE_VOS(OProcess)::TOption_Detached*/
                            /*| NAMESPACE_VOS(OProcess)::TOption_Wait*/ ),
                            *pArgumentList,
                            *pEnvList ) == NAMESPACE_VOS(OProcess)::E_None;
            }
            else
            {
                bSuccess = pProcess->execute( (NAMESPACE_VOS(OProcess)::TProcessOption)
                            ( NAMESPACE_VOS(OProcess)::TOption_SearchPath
                            /*| NAMESPACE_VOS(OProcess)::TOption_Detached*/
                            /*| NAMESPACE_VOS(OProcess)::TOption_Wait*/ ),
                            *pArgumentList ) == NAMESPACE_VOS(OProcess)::E_None;
            }
#ifdef WNT
        }
        catch( ... )
        {
            bWasGPF = TRUE;
        }
        nErrorMode = SetErrorMode(nErrorMode);
#endif
        bHasBeenStarted = bSuccess;
    }
    else
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
    return bSuccess;
}

ULONG Process::GetExitCode()
{ // ExitCode des Programms(nachdem es beendet ist)
    return ImplGetExitCode();
}

BOOL Process::IsRunning()
{ // Programm luft noch
    return ImplIsRunning();
}

BOOL Process::WasGPF()
{ // Programm mit GPF o.. abgebrochen
#ifdef WNT
    return ImplGetExitCode() == 3221225477;
#else
    return bWasGPF;
#endif
}

BOOL Process::Terminate()
{
    if ( ImplIsRunning() )
        return pProcess->terminate() == vos::OProcess::E_None;
    return TRUE;
}

<|endoftext|>


<commit_before>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/ToolOutputFile.h"
#include "mlir/IR/Diagnostics.h"  // TF:local_config_mlir
#include "mlir/IR/Function.h"  // TF:local_config_mlir
#include "mlir/IR/MLIRContext.h"  // TF:local_config_mlir
#include "mlir/IR/Module.h"  // TF:local_config_mlir
#include "mlir/Support/FileUtilities.h"  // TF:local_config_mlir
#include "tensorflow/compiler/mlir/init_mlir.h"
#include "tensorflow/compiler/mlir/lite/common/tfl_pass_config.h"
#include "tensorflow/compiler/mlir/lite/flatbuffer_translate.h"
#include "tensorflow/compiler/mlir/lite/tf_tfl_passes.h"
#include "tensorflow/compiler/mlir/lite/tf_tfl_translate_cl.h"
#include "tensorflow/compiler/mlir/lite/tf_to_tfl_flatbuffer.h"
#include "tensorflow/compiler/mlir/tensorflow/translate/tf_mlir_translate_cl.h"
#include "tensorflow/core/platform/init_main.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "tensorflow/stream_executor/lib/statusor.h"

using mlir::FuncOp;
using mlir::MLIRContext;
using mlir::ModuleOp;
using stream_executor::port::StatusOr;

// Debugging flag to print function mapping in the flatbuffer.
// NOLINTNEXTLINE
static llvm::cl::opt<bool> print_function_result_mapping(
    "print-function-result-mapping",
    llvm::cl::desc(
        "Print the mapping of function result to flatbuffer output buffer"),
    llvm::cl::init(false));

enum TranslationStatus { kTrSuccess, kTrFailure };

static int PrintFunctionResultMapping(const std::string &result,
                                      ModuleOp module) {
  // Build model from the resultant string to extract the return values from
  // their source of truth.
  auto model =
      tflite::FlatBufferModel::BuildFromBuffer(result.data(), result.size());
  if (!model) return kTrFailure;

  // Get an unknown location for where we don't have a terminator to get the
  // location of the return value from.
  auto unknown_loc = mlir::UnknownLoc::get(module.getContext());

  auto print_buffer = [&](const tflite::SubGraph &subgraph, int id, int buffer,
                          std::function<mlir::Location(int)> loc) {
    const auto &output_tensor = (*subgraph.tensors())[buffer];
    std::cout << "\tname: '"
              << (output_tensor->name() ? output_tensor->name()->str()
                                        : "<<unnamed>>")
              << "' buffer: " << buffer;
    if (loc) std::cout << llvm::formatv(" {0}", loc(id)).str();
    std::cout << '\n';
  };

  // For every subgraph print out the name (if available), each result's output
  // buffer number and location of the return value (if available).
  for (auto *subgraph : *(*model)->subgraphs()) {
    std::string subgraph_name =
        subgraph->name() ? subgraph->name()->str() : "<<unnamed subgraph>>";

    std::cout << '\'' << subgraph_name << "' inputs:\n";
    int i = 0;
    for (auto input : *subgraph->inputs())
      print_buffer(*subgraph, i++, input, nullptr);

    std::cout << '\'' << subgraph_name << "' outputs:\n";
    mlir::Operation *terminator = nullptr;
    if (subgraph->name()) {
      if (auto fn = module.lookupSymbol<FuncOp>(subgraph->name()->str()))
        terminator = fn.back().getTerminator();
    }
    i = 0;
    for (auto output : *subgraph->outputs()) {
      print_buffer(*subgraph, i, output, [&](int i) {
        return terminator ? terminator->getOperand(i)->getLoc() : unknown_loc;
      });
    }
  }
  return kTrSuccess;
}

int main(int argc, char **argv) {
  // TODO(jpienaar): Revise the command line option parsing here.
  tensorflow::InitMlir y(&argc, &argv);

  // TODO(antiagainst): We are pulling in multiple transformations as follows.
  // Each transformation has its own set of command-line options; options of one
  // transformation can essentially be aliases to another. For example, the
  // -tfl-annotate-inputs has -tfl-input-arrays, -tfl-input-data-types, and
  // -tfl-input-shapes, which are the same as -graphdef-to-mlir transformation's
  // -tf_input_arrays, -tf_input_data_types, and -tf_input_shapes, respectively.
  // We need to disable duplicated ones to provide a cleaner command-line option
  // interface. That also means we need to relay the value set in one option to
  // all its aliases.
  llvm::cl::ParseCommandLineOptions(
      argc, argv, "TF GraphDef to TFLite FlatBuffer converter\n");

  MLIRContext context;
  llvm::SourceMgr source_mgr;
  mlir::SourceMgrDiagnosticHandler sourceMgrHandler(source_mgr, &context);

  StatusOr<mlir::OwningModuleRef> module =
      tensorflow::LoadFromGraphdefOrMlirSource(
          input_file_name, input_mlir, use_splatted_constant, extra_opdefs,
          debug_info_file, input_arrays, input_dtypes, input_shapes,
          output_arrays, inference_type, min_values, max_values,
          /*prune_unused_nodes=*/true, &source_mgr, &context);

  // If errors occur, the library call in the above already logged the error
  // message. So we can just return here.
  if (!module.ok()) return kTrFailure;

  mlir::PassManager pm(&context);
  bool run_quantize =
      tensorflow::ShouldRunQuantizePasses(module.ValueOrDie().get());
  mlir::TFL::PassConfig pass_config;
  pass_config.emit_builtin_tflite_ops = emit_builtin_tflite_ops;
  pass_config.emit_quant_adaptor_ops = emit_quant_adaptor_ops;
  pass_config.lower_tensor_list_ops = lower_tensor_list_ops;
  pass_config.run_quantize = run_quantize;

  tensorflow::AddTFToTFLConversionPasses(pass_config, &pm);

  std::string result;
  auto status = tensorflow::ConvertTFExecutorToTFLOrFlatbuffer(
      module.ValueOrDie().get(), output_mlir, emit_builtin_tflite_ops,
      emit_select_tf_ops, emit_custom_ops, emit_quant_adaptor_ops,
      lower_tensor_list_ops, &result, &pm);
  if (!status.ok()) return kTrFailure;

  auto output = mlir::openOutputFile(output_file_name);
  output->os() << result;
  output->keep();

  // Print out debugging info related to function mapping.
  if (print_function_result_mapping)
    return PrintFunctionResultMapping(result, module.ValueOrDie().get());
  return kTrSuccess;
}
<commit_msg>Add error handling of mlir::openOutputFile<commit_after>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/ToolOutputFile.h"
#include "mlir/IR/Diagnostics.h"  // TF:local_config_mlir
#include "mlir/IR/Function.h"  // TF:local_config_mlir
#include "mlir/IR/MLIRContext.h"  // TF:local_config_mlir
#include "mlir/IR/Module.h"  // TF:local_config_mlir
#include "mlir/Support/FileUtilities.h"  // TF:local_config_mlir
#include "tensorflow/compiler/mlir/init_mlir.h"
#include "tensorflow/compiler/mlir/lite/common/tfl_pass_config.h"
#include "tensorflow/compiler/mlir/lite/flatbuffer_translate.h"
#include "tensorflow/compiler/mlir/lite/tf_tfl_passes.h"
#include "tensorflow/compiler/mlir/lite/tf_tfl_translate_cl.h"
#include "tensorflow/compiler/mlir/lite/tf_to_tfl_flatbuffer.h"
#include "tensorflow/compiler/mlir/tensorflow/translate/tf_mlir_translate_cl.h"
#include "tensorflow/core/platform/init_main.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "tensorflow/stream_executor/lib/statusor.h"

using mlir::FuncOp;
using mlir::MLIRContext;
using mlir::ModuleOp;
using stream_executor::port::StatusOr;

// Debugging flag to print function mapping in the flatbuffer.
// NOLINTNEXTLINE
static llvm::cl::opt<bool> print_function_result_mapping(
    "print-function-result-mapping",
    llvm::cl::desc(
        "Print the mapping of function result to flatbuffer output buffer"),
    llvm::cl::init(false));

enum TranslationStatus { kTrSuccess, kTrFailure };

static int PrintFunctionResultMapping(const std::string &result,
                                      ModuleOp module) {
  // Build model from the resultant string to extract the return values from
  // their source of truth.
  auto model =
      tflite::FlatBufferModel::BuildFromBuffer(result.data(), result.size());
  if (!model) return kTrFailure;

  // Get an unknown location for where we don't have a terminator to get the
  // location of the return value from.
  auto unknown_loc = mlir::UnknownLoc::get(module.getContext());

  auto print_buffer = [&](const tflite::SubGraph &subgraph, int id, int buffer,
                          std::function<mlir::Location(int)> loc) {
    const auto &output_tensor = (*subgraph.tensors())[buffer];
    std::cout << "\tname: '"
              << (output_tensor->name() ? output_tensor->name()->str()
                                        : "<<unnamed>>")
              << "' buffer: " << buffer;
    if (loc) std::cout << llvm::formatv(" {0}", loc(id)).str();
    std::cout << '\n';
  };

  // For every subgraph print out the name (if available), each result's output
  // buffer number and location of the return value (if available).
  for (auto *subgraph : *(*model)->subgraphs()) {
    std::string subgraph_name =
        subgraph->name() ? subgraph->name()->str() : "<<unnamed subgraph>>";

    std::cout << '\'' << subgraph_name << "' inputs:\n";
    int i = 0;
    for (auto input : *subgraph->inputs())
      print_buffer(*subgraph, i++, input, nullptr);

    std::cout << '\'' << subgraph_name << "' outputs:\n";
    mlir::Operation *terminator = nullptr;
    if (subgraph->name()) {
      if (auto fn = module.lookupSymbol<FuncOp>(subgraph->name()->str()))
        terminator = fn.back().getTerminator();
    }
    i = 0;
    for (auto output : *subgraph->outputs()) {
      print_buffer(*subgraph, i, output, [&](int i) {
        return terminator ? terminator->getOperand(i)->getLoc() : unknown_loc;
      });
    }
  }
  return kTrSuccess;
}

int main(int argc, char **argv) {
  // TODO(jpienaar): Revise the command line option parsing here.
  tensorflow::InitMlir y(&argc, &argv);

  // TODO(antiagainst): We are pulling in multiple transformations as follows.
  // Each transformation has its own set of command-line options; options of one
  // transformation can essentially be aliases to another. For example, the
  // -tfl-annotate-inputs has -tfl-input-arrays, -tfl-input-data-types, and
  // -tfl-input-shapes, which are the same as -graphdef-to-mlir transformation's
  // -tf_input_arrays, -tf_input_data_types, and -tf_input_shapes, respectively.
  // We need to disable duplicated ones to provide a cleaner command-line option
  // interface. That also means we need to relay the value set in one option to
  // all its aliases.
  llvm::cl::ParseCommandLineOptions(
      argc, argv, "TF GraphDef to TFLite FlatBuffer converter\n");

  MLIRContext context;
  llvm::SourceMgr source_mgr;
  mlir::SourceMgrDiagnosticHandler sourceMgrHandler(source_mgr, &context);

  StatusOr<mlir::OwningModuleRef> module =
      tensorflow::LoadFromGraphdefOrMlirSource(
          input_file_name, input_mlir, use_splatted_constant, extra_opdefs,
          debug_info_file, input_arrays, input_dtypes, input_shapes,
          output_arrays, inference_type, min_values, max_values,
          /*prune_unused_nodes=*/true, &source_mgr, &context);

  // If errors occur, the library call in the above already logged the error
  // message. So we can just return here.
  if (!module.ok()) return kTrFailure;

  mlir::PassManager pm(&context);
  bool run_quantize =
      tensorflow::ShouldRunQuantizePasses(module.ValueOrDie().get());
  mlir::TFL::PassConfig pass_config;
  pass_config.emit_builtin_tflite_ops = emit_builtin_tflite_ops;
  pass_config.emit_quant_adaptor_ops = emit_quant_adaptor_ops;
  pass_config.lower_tensor_list_ops = lower_tensor_list_ops;
  pass_config.run_quantize = run_quantize;

  tensorflow::AddTFToTFLConversionPasses(pass_config, &pm);

  std::string result;
  auto status = tensorflow::ConvertTFExecutorToTFLOrFlatbuffer(
      module.ValueOrDie().get(), output_mlir, emit_builtin_tflite_ops,
      emit_select_tf_ops, emit_custom_ops, emit_quant_adaptor_ops,
      lower_tensor_list_ops, &result, &pm);
  if (!status.ok()) return kTrFailure;

  std::string error_msg;
  auto output = mlir::openOutputFile(output_file_name, &error_msg);
  if (output == nullptr) {
    llvm::errs() << error_msg << '\n';
    return kTrFailure;
  }
  output->os() << result;
  output->keep();

  // Print out debugging info related to function mapping.
  if (print_function_result_mapping)
    return PrintFunctionResultMapping(result, module.ValueOrDie().get());
  return kTrSuccess;
}
<|endoftext|>