ppovb5fc7/gazebo/test/integration/SimplePendulumIntegrator.hh

74 lines
2.2 KiB
C++

/*
* Copyright (C) 2012 Open Source Robotics Foundation
*
* 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.
*
*/
/* Desc: Simple pendulum motion integrator
* Author: John Hsu
* Date: 2012/04/20
*/
#include <math.h>
// integrate d^2 theta / dt^2 = - g * sin(theta) / l
// by discretizing via central differencing (requires very small dt)
// (theta_2 - 2*theta_1 + theta_2) / dt^2 = -g * sin(theta_1) / l
//
// or euler + 3-4-1 backward Euler is 2nd order:
//
// (2*theta_2 - 5*theta_1 + 4*theta_2 -theta_3) / dt^2
// = -g * sin(theta_1) / l
//
// where thata_3 is theta(t - 3*dt)
// thata_2 is theta(t - 2*dt)
// thata_1 is theta(t - dt)
// and
// thata_f or theta(t_f) is the solution returned
//
// If pendulum starts out stationary, one can assume
// theta_3 = theta_2 = theta_1 = theta_i
//
double PendulumAngle(double g, double l, double theta_i,
double t_i, double t_f , double dt)
{
double theta_3 = theta_i;
double theta_2 = theta_i;
double theta_1 = theta_i;
double theta_f = theta_i;
int steps = ceil((t_f - t_i) / dt);
double t = t_i;
for (int i = 0 ; i < steps; i++)
{
t += dt;
theta_f = (-dt*dt*g*sin(theta_1)/l
+ theta_3
- 4.0*theta_2
+ 5.0*theta_1)/2.0;
/*
theta_f = (-dt*dt*g*sin(theta_1)/l
- 1.0*theta_2
+ 2.0*theta_1);
*/
// next step
theta_3 = theta_2;
theta_2 = theta_1;
theta_1 = theta_f;
// printf("debug t[%f] t_f[%f] theta_f[%f]\n", t, t_f, theta_f);
}
if (fabs(t - t_f) > 0.000001)
printf("time mismatch t[%f] t_f[%f] theta_f[%f]\n", t, t_f, theta_f);
return theta_f;
}