# ChronoEngine:Demo chfunctions

(diff) ← Older revision | Current revision (diff) | Newer revision → (diff)

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.

These functions are scalar, $x \in \mathbb{R} \rightarrow y \in \mathbb{R}$, and there are a predefined number of them that are ready to use, such as sine, cosine, constant, etc. If the predefined ones are not enough, the user can implement his custom function by inheriting from the base ChFunction class.

In this tutorial learn how:

• create and use ChFunction objects, from available classes.
• define a custom function by inheriting from ChFunction class.

## Contents

### Example 1

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);

GetLog() << "   ChFunction_Ramp at x=0: y=" << y << "  dy/dx=" << ydx << "\n\n";


### Example 2

Save values of a sine ChFunction into a file.

ChFunction_Sine f_sine;

f_sine.Set_amp(2);		// set amplitude;
f_sine.Set_freq(1.5);	// set frequency;

ChStreamOutAsciiFile file_f_sine ("f_sine_out.dat");

// 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)
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

Define a custom function.

The following class will be used as an example of 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.

// First, define a custom class inherited from ChFunction

class ChFunction_MyTest : public ChFunction
{
public:
ChFunction* new_Duplicate() {return new ChFunction_MyTest;}
double Get_y(double x) {return cos(x);} // just for test: simple cosine
};

ChFunction_MyTest f_test;

ChStreamOutAsciiFile file_f_test ("f_test_out.dat");

// 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)
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.

ChFunction_Sequence f_sequence;

ChFunction_ConstAcc* f_constacc1 = new ChFunction_ConstAcc;
f_constacc1->Set_end(0.5); // length of ramp
f_constacc1->Set_h(0.3);   // height of ramp
f_sequence.InsertFunct(f_constacc1, 0.5, 1, false, false, false, 0);

ChFunction_Const* f_const = new ChFunction_Const;
f_sequence.InsertFunct(f_const, 0.4, 1, true, false, false, -1);

ChFunction_ConstAcc* f_constacc2 = new 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.InsertFunct(f_constacc2, 0.6, 1, true, false, false, -1);

f_sequence.Setup();

ChStreamOutAsciiFile file_f_sequence ("f_sequence_out.dat");

// 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 )
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";
}