Using ChFunctions in Chrono (demo_CH_functions.cpp) 
  Tutorial that teaches how to use the ChFunction inherited classes to build math functions of y=f(x) type. The ChFunction objects are 'building blocks' whose main usage is to describe motion laws, such as trajectories in automation and robotics, etc.
- create and use ChFunction objects, from available classes.
- define a custom function by inheriting from ChFunction class.
- use the ChFunction_Sequence to build a sequence of basic functions
- No GUI: only text output.
// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Alessandro Tasora, Radu Serban
// =============================================================================
//
// Demo code for using the ChFunction objects for specifying functions y=f(t)
//
// =============================================================================
#include "chrono/core/ChGlobal.h"
#include "chrono/motion_functions/ChFunction.h"
#include "chrono_thirdparty/filesystem/path.h"
// Use the namespace of Chrono
using namespace chrono;
int main(int argc, char* argv[]) {
    // Create (if needed) output directory
    if (!filesystem::create_directory(filesystem::path(out_dir))) {
        std::cout << "Error creating directory " << out_dir << std::endl;
        return 1;
    }
    //
    // EXAMPLE 1: create a ramp ChFunction, set properties, evaluate it.
    //
    GetLog() << "==== Test 1...\n\n";
    ChFunction_Ramp f_ramp;
    f_ramp.Set_ang(0.1);  // set angular coefficient;
    f_ramp.Set_y0(0.4);   // set y value for x=0;
    // Evaluate y=f(x) function at a given x value, using Get_y() :
    double y = f_ramp.Get_y(10);
    // Evaluate derivative df(x)/dx at a given x value, using Get_y_dx() :
    double ydx = f_ramp.Get_y_dx(10);
    //
    // EXAMPLE 2: save values of a sine ChFunction  into a file
    //
    GetLog() << "==== Test 2...\n\n";
    ChFunction_Sine f_sine;
    f_sine.Set_amp(2);     // set amplitude;
    f_sine.Set_freq(1.5);  // set frequency;
    std::string sinefile = out_dir + "/f_sine_out.dat";
    ChStreamOutAsciiFile file_f_sine(sinefile.c_str());
    // Evaluate y=f(x) function along 100 x points, and its derivatives,
    // and save to file (later it can be loaded, for example, in Matlab using the 'load()' command)
    for (int i = 0; i < 100; i++) {
        double x = (double)i / 50.0;
        double y = f_sine.Get_y(x);
        double ydx = f_sine.Get_y_dx(x);
        double ydxdx = f_sine.Get_y_dxdx(x);
        file_f_sine << x << " " << y << " " << ydx << " " << ydxdx << "\n";
    }
    //
    // EXAMPLE 3: use a custom function (see class at the beginning of this file)
    //
    GetLog() << "==== Test 3...\n\n";
    // The following class will be used as an example of how
    // how you can create custom functions based on the ChFunction interface.
    // There is at least one mandatory member function to implement:  Get_y().
    // [Note that the base class implements a default computation of derivatives
    // Get_ydx() and Get_ydxdx() by using a numerical differentiation, however
    // if you know the analytical expression of derivatives, you can override
    // the base Get_ydx() and Get_ydxdx() too, for higher precision.]
      public:
        virtual ChFunction_MyTest* Clone() const override { return new ChFunction_MyTest(); }
        virtual double Get_y(double x) const override { return cos(x); }  // just for test: simple cosine
    };
    ChFunction_MyTest f_test;
    std::string testfile = out_dir + "/f_test_out.dat";
    ChStreamOutAsciiFile file_f_test(testfile.c_str());
    // Evaluate y=f(x) function along 100 x points, and its derivatives,
    // and save to file (later it can be loaded, for example, in Matlab using the 'load()' command)
    for (int i = 0; i < 100; i++) {
        double x = (double)i / 50.0;
        double y = f_test.Get_y(x);
        double ydx = f_test.Get_y_dx(x);
        double ydxdx = f_test.Get_y_dxdx(x);
        file_f_test << x << " " << y << " " << ydx << " " << ydxdx << "\n";
    }
    //
    // EXAMPLE 4: mount some functions in a sequence using ChFunction_Sequence
    //
    GetLog() << "==== Test 4...\n\n";
    ChFunction_Sequence f_sequence;
    auto f_constacc1 = chrono_types::make_shared<ChFunction_ConstAcc>();
    f_constacc1->Set_end(0.5);  // length of ramp
    f_constacc1->Set_h(0.3);    // height of ramp
    auto f_const = chrono_types::make_shared<ChFunction_Const>();
    auto f_constacc2 = chrono_types::make_shared<ChFunction_ConstAcc>();
    f_constacc2->Set_end(0.6);  // length of ramp
    f_constacc2->Set_av(0.3);   // acceleration ends after 30% length
    f_constacc2->Set_aw(0.7);   // deceleration starts after 70% length
    f_constacc2->Set_h(-0.2);   // height of ramp
    f_sequence.Setup();
    std::string seqfile = out_dir + "/f_sequence_out.dat";
    ChStreamOutAsciiFile file_f_sequence(seqfile.c_str());
    // Evaluate y=f(x) function along 100 x points, and its derivatives,
    // and save to file (later it can be loaded, for example, in Matlab using the 'load()' command)
    for (int i = 0; i < 100; i++) {
        double x = (double)i / 50.0;
        double y = f_sequence.Get_y(x);
        double ydx = f_sequence.Get_y_dx(x);
        double ydxdx = f_sequence.Get_y_dxdx(x);
        file_f_sequence << x << " " << y << " " << ydx << " " << ydxdx << "\n";
    }
    //
    // EXAMPLE 5: a repeating sequence
    //
    GetLog() << "==== Test 5...\n\n";
    auto f_part1 = chrono_types::make_shared<ChFunction_Ramp>();
    f_part1->Set_ang(.50);
    auto f_part2 = chrono_types::make_shared<ChFunction_Const>();
    f_part2->Set_yconst(1.0);
    auto f_part3 = chrono_types::make_shared<ChFunction_Ramp>();
    f_part3->Set_ang(-.50);
    auto f_seq = chrono_types::make_shared<ChFunction_Sequence>();
    f_seq->InsertFunct(f_part1, 1.0, 1, true);
    f_seq->InsertFunct(f_part2, 1.0, 1., true);
    f_seq->InsertFunct(f_part3, 1.0, 1., true);
    auto f_rep_seq = chrono_types::make_shared<ChFunction_Repeat>();
    f_rep_seq->Set_fa(f_seq);
    f_rep_seq->Set_window_length(3.0);
    f_rep_seq->Set_window_start(0.0);
    f_rep_seq->Set_window_phase(3.0);
    std::string repeatfile = out_dir + "/f_repeat_out.dat";
    ChStreamOutAsciiFile file_f_repeat(repeatfile.c_str());
    for (int i = 0; i < 1000; i++) {
        double x = (double)i / 50.0;
        double y = f_rep_seq->Get_y(x);
        double ydx = f_rep_seq->Get_y_dx(x);
        double ydxdx = f_rep_seq->Get_y_dxdx(x);
        file_f_repeat << x << " " << y << " " << ydx << " " << ydxdx << "\n";
    }
    return 0;
}
Sine function y = sin (phase + w*x ) where w=2*PI*freq.
Definition: ChFunction_Sine.h:27
Interface base class for scalar functions of the type: y= f(x)
Definition: ChFunction_Base.h:45
void Set_y0(double m_y0)
The value for x=0;.
Definition: ChFunction_Ramp.h:48
bool InsertFunct(std::shared_ptr< ChFunction > myfx, double duration, double weight=1, bool c0=false, bool c1=false, bool c2=false, int position=-1)
Insert function after the fx with defined "position" index in list.
Definition: ChFunction_Sequence.cpp:108
void Setup()
Scans all the seq.of functions and setup the timings and continuity offsets, to satisfy all constrain...
Definition: ChFunction_Sequence.cpp:203
ChLog & GetLog()
Global function to get the current ChLog object.
Definition: ChLog.cpp:39
Linear function (like a straight ramp): y = y0 + x * speed
Definition: ChFunction_Ramp.h:27
virtual double Get_y(double x) const override
Return the y value of the function, at position x.
Definition: ChFunction_Ramp.h:43
virtual double Get_y(double x) const override
Return the y value of the function, at position x.
Definition: ChFunction_Sine.cpp:29
const std::string & GetChronoOutputPath()
Obtain the path to the output directory for Chrono demos.
Definition: ChGlobal.cpp:110
virtual double Get_y_dxdx(double x) const override
Return the ddy/dxdx double derivative of the function, at position x.
Definition: ChFunction_Sine.cpp:37
void Set_ang(double m_ang)
The angular coefficient.
Definition: ChFunction_Ramp.h:52
virtual double Get_y_dx(double x) const override
Return the dy/dx derivative of the function, at position x.
Definition: ChFunction_Ramp.h:44
virtual double Get_y_dx(double x) const override
Return the dy/dx derivative of the function, at position x.
Definition: ChFunction_Sine.cpp:33
virtual double Get_y_dx(double x) const override
Return the dy/dx derivative of the function, at position x.
Definition: ChFunction_Sequence.cpp:263
This is a specialized class for ASCII output on system's file,.
Definition: ChStream.h:789
virtual double Get_y(double x) const override
Return the y value of the function, at position x.
Definition: ChFunction_Sequence.cpp:251
virtual double Get_y_dxdx(double x) const override
Return the ddy/dxdx double derivative of the function, at position x.
Definition: ChFunction_Sequence.cpp:275
Sequence function: y = sequence_of_functions(f1(y), f2(y), f3(y)) All other function types can be ins...
Definition: ChFunction_Sequence.h:68
