automobile_simple.cc

00001 /*
00002  * automobile_simple.cc
00003  *
00004  * Programmer(s): Michael Paluszek
00005  *
00006  * Copyright (c) 2013 Princeton Satellite Systems. All rights reserved.
00007  *
00008  */
00009 
00010 #include "automobile_simple.h"
00011 #include <math.h>
00012 
00013 
00014 automobile_simple::automobile_simple(dsim_model_setup *setup) : dsim_model(setup)
00015 {
00016 }
00017 
00018 automobile_simple::~automobile_simple()
00019 {
00020 }
00021         
00022 void automobile_simple::initialize_data()
00023 {               
00024     // Parameters
00025     double steering_angle           = 0;
00026     double torque                   = 0;
00027     double rolling_friction_coeff   = 0.01; // Ordinary car tires on concrete
00028     double mass                     = 907.1890;
00029     double inertia                  = 514.0709;
00030     double rho                      = 0.2;
00031     double drag_coeff               = 0.25;
00032     double frontal_area             = 4.0;
00033     ml_matrix r                     = "[1.2 1.2 -1 -1;-0.7 0.7 -0.7 0.7]";
00034     ml_matrix state(6,1);
00035     ml_matrix position(2,1);
00036     ml_matrix yaw_matrix(2,2); yaw_matrix.identity();
00037     
00038  
00039     steering_angle_dsim         = create_input("steering_angle",                sd_type_double, &steering_angle,            1,1,    "rad",              "Steering angle");
00040     torque_dsim                 = create_input("torque",                        sd_type_double, &torque,                    1,1,    "Nm",               "Motor torque");
00041     
00042     rolling_friction_coeff_dsim = create_parameter("rolling_friction_coeff",    sd_type_double, &rolling_friction_coeff,    1,1,    "",                 "Rolling friction coefficient"); 
00043     drag_coeff_dsim             = create_parameter("drag_coeff_coeff",          sd_type_double, &drag_coeff,                1,1,    "",                 "Drag coefficient"); 
00044     frontal_area_dsim           = create_parameter("frontal_area",              sd_type_double, &frontal_area,              1,1,    "m^2",              "Frontal area"); 
00045     inertia_dsim                = create_parameter("inertia",                   sd_type_double, &inertia,                   1,1,    "kg-m^2",           "Yaw inertia"); 
00046     mass_dsim                   = create_parameter("mass",                      sd_type_double, &mass,                      1,1,    "kg",               "Rolling friction coefficient"); 
00047     r_dsim                      = create_parameter("r",                         sd_type_double, &r,                         2,4,    "m",                "Tire position"); 
00048     rho_dsim                    = create_parameter("rho",                       sd_type_double, &rho,                       1,1,    "m",                "Tire radius"); 
00049     
00050     state_dsim                  = create_integrated_state("state",              sd_type_matrix, &state,                     6,1,    "m,m/s,rad,rad/s",  "State"); 
00051     position_dsim               = create_output("position",                     sd_type_matrix, &position,                  2,1,    "m",                "Position");
00052     yaw_matrix_dsim             = create_output("yaw_matrix",                   sd_type_matrix, &yaw_matrix,                2,2,    "",                 "Yaw rotation matrix");
00053   
00054     steering_angle_dsim.mark_telemetry_and_command();
00055     torque_dsim.mark_telemetry_and_command();
00056     rolling_friction_coeff_dsim.mark_telemetry();
00057     inertia_dsim.mark_telemetry();
00058     mass_dsim.mark_telemetry();
00059     rho_dsim .mark_telemetry();
00060     r_dsim.mark_telemetry();
00061     state_dsim.mark_telemetry();
00062     position_dsim.mark_telemetry();
00063     yaw_matrix_dsim.mark_telemetry();
00064     drag_coeff_dsim.mark_telemetry();
00065     frontal_area_dsim.mark_telemetry();
00066     
00067     configure_timestep(false,true,false);
00068 }
00069 
00070 void automobile_simple::initialization_complete()
00071 {
00072 }
00073 
00074 void automobile_simple::initialize_timestep()
00075 {
00076 }
00077 
00078 void automobile_simple::rhs(double t,double jd)
00079 {
00080     double delta    = steering_angle_dsim.value_as_double();
00081     double torque   = torque_dsim.value_as_double();
00082     double cF       = rolling_friction_coeff_dsim.value_as_double();
00083     double inr      = inertia_dsim.value_as_double();
00084     double m        = mass_dsim.value_as_double();
00085     double rho      = rho_dsim.value_as_double();
00086     double c_d      = drag_coeff_dsim.value_as_double();
00087     double a        = frontal_area_dsim.value_as_double();
00088     ml_matrix r     = r_dsim.value_as_matrix();
00089     ml_matrix x     = state_dsim.value_as_matrix();
00090     
00091     const double g = 9.806; // Acceleration of gravity (m/s^2)
00092     
00093     // Local variables
00094     double vX       = x.get(3,1);
00095     double vY       = x.get(4,1);
00096     double omega    = x.get(6,1);
00097     
00098     double f_friction = -cF*m*g;
00099     
00100     if( vX <= 0 ) f_friction = 0;
00101     double f_traction = 0.5*torque/rho + f_friction;
00102     
00103     ml_matrix x_dot(6,1);
00104     
00105     // Kinematics
00106     x_dot(1,1)      = vX;
00107     x_dot(2,1)      = vY;
00108     x_dot(5,1)      = omega;
00109     
00110     // Cosine and sine of the wheel angles
00111     double c        = cos(delta);
00112     double s        = sin(delta);
00113     
00114     // Force components
00115     double fX1      = f_traction*c;
00116     double fY1      = f_traction*s;
00117     
00118     double fX2      = f_traction*c;
00119     double fY2      = f_traction*s;
00120     
00121     double fX3      = f_friction;
00122     double fY3      = 0;
00123     
00124     double fX4      = f_friction;
00125     double fY4      = 0;
00126     
00127     // Force summations
00128     double fX       = fX1 + fX2 + fX3 + fX4 - 0.5*1.225*c_d*a*pow(vX,2);
00129     double fY       = fY1 + fY2 + fY3 + fY4;
00130     
00131     // Dynamical equations in the body frame
00132     x_dot(3,1)      = fX/m + omega*vY;
00133     x_dot(4,1)      = fY/m - omega*vX;
00134     
00135     // Torque
00136     double T        = r.get(2,1)*fX1 - r.get(1,1)*fY1 + r.get(2,2)*fX2 - r.get(1,2)*fY2
00137                     + r.get(2,3)*fX3 - r.get(1,3)*fY3 + r.get(2,4)*fX4 - r.get(1,4)*fY4;
00138     
00139     // Yaw dynamics
00140     x_dot(6,1)      = T/inr;
00141    
00142     state_dsim.set_derivative(x_dot);
00143 }
00144 
00145 void automobile_simple::complete_timestep()
00146 {
00147         dsim_model::complete_timestep();
00148     
00149     ml_matrix state = state_dsim.value_as_matrix();
00150     double theta    = state.get(5,1);
00151     double c        = cos(theta);
00152     double s        = sin(theta);
00153     
00154     ml_matrix yaw_matrix(2,2); yaw_matrix(1,1) = c; yaw_matrix(1,2) = s; yaw_matrix(2,1) = -s; yaw_matrix(2,2) = c;
00155     ml_matrix pos = yaw_matrix*state.sub_matrix(1,2,1,1);
00156     
00157     position_dsim.set_value_as_matrix(pos);
00158     yaw_matrix_dsim.set_value_as_matrix(yaw_matrix);
00159 
00160 }
00161 
00162 extern "C"
00163 {
00164     dsim_model *AutomobileSimple(void *setup);
00165 
00166         dsim_model *AutomobileSimple(void *setup)
00167         {
00168                 return new automobile_simple((dsim_model_setup *)setup);
00169         }       
00170 }
 All Classes Files Functions Variables