Electromechanical Design: Motor Control

For this project, we were tasked with moving an upright beam between 2 points as quickly as possible. We were provided a 12V motor with encoder, an Arduino and the vehicle’s axle and belt. The rest was up to our team.

Calculations & Simulation

The max acceleration was calculated by measuring the reaction force on the front edge of the beam as a linear acceleration was applied.

By measuring the motors max RPM, we were then able to solve for the ideal wheel size of 4.631 Inches

Design

Employing the laser cutter instead of the 3d printer allowed the team to iterate faster, dialing in press-fit tolerances in minutes instead of hours.

The wheel diameter was reduced to 4.61” to allow for rubber bands providing much needed traction.

Code

The bulk of the code is handling a velocity profile follower to ensure the maximum acceleration is never overcome.

Important variables for fine tuning included:

  • Max Velocity

  • Max Acceleration

  • Distance Traveled

  • Ramp Constant

  • Min Power

  • Max Power

double t_accel  = vmax / accel;                                   // time to reach vMax
double d_ramp   = (vmax * vmax)/(2 * accel);                      // distance in one ramp (v^2/2a)
double d_needed = dist;
double cruiseTime = 0.0;
double peakV = vmax;                                              // might be less if triangular
// Check if triangular (can't reach vMax within distance)
if (2.0 * d_ramp > d_needed) {
  // Triangular: solve for peak velocity from distance = v^2/a
  peakV = sqrt(d_needed * accel);
  t_accel = peakV / accel;
  cruiseTime = 0.0;
} else {
  // Trapezoidal: cruise for the leftover distance at vMax
  double d_cruise = d_needed - 2.0 * d_ramp;
  cruiseTime = d_cruise / vmax;
}
// Convert speeds to PWM ceilings via calibration
int pwm_peak = PWM_MIN + (int)round(peakV * K_PWM_PER_IPS);
pwm_peak = constrain(pwm_peak, PWM_MIN, PWM_MAX_CAP);
// Choose a smooth PWM step and time step so accelTime is honored
int   stepsAccel = max(1, pwm_peak - PWM_MIN);
double dtAccel   = t_accel / (double)stepsAccel;
// ===== Acceleration =====
for (int i = 0; i < stepsAccel; i++) {
  int pwm = PWM_MIN + i;
  analogWrite(drivePin, pwm);
  delay((unsigned long)(dtAccel * 1000.0));
}
analogWrite(drivePin, pwm_peak);
// ===== Cruise Time =====
if (cruiseTime > 0.0) {
  delay((unsigned long)(cruiseTime * 1000.0));
}
Previous
Previous

Motion Studies