Final touches…

28 January 2012

…before I move on to implementing the lateral balance controller.

I’ve increased the ground velocity gain to reduce the swaying evident in my previous update. I’ve also added an integrator to dynamically align the intended center of mass pitch angle with the actual center of mass to maintain an upright posture in the presence of temperature drift and changes in weight distribution (battery shift etc.), for which a simple programmed offset cannot fix.

Added position feedback

28 January 2012

…and increased wheel velocity gain:

Still no integration of pendulum angle, the lack of which probably contributes the cause of the ground motion limit cycle you see. Still, I’m quite chuffed it works this well without much effort at all!

 

First sign of life

26 January 2012

I successfully instated a very primitive control loop to regulate the base wheel drive torque. It employs pitch angle, pitch rate and wheel rate feedback. In the video below, the pitch angle was manually zeroed, so the robot tends to drift in one direction. Clearly, I’m also relying on the training wheel for lateral support, so at best I’m only halfway there 🙂

test jig

9 January 2012

I didn’t get quite as far as parameter estimation or controller design as I’d hoped in my previous update. I decided instead to spend some time building a test jig to replace the hastily designed and not surprisingly ineffective safety bumper (white bucket). It was also a good opportunity to give a the desk a bit of a tidy-up:

The test jig is an aluminum rail mounted on two wooden posts, the robot is tethered to a cart that rolls along the rails.

Baby steps

4 January 2012

As you can see, I haven’t gone away; I’m going with stylishly late entries 😉

At this point, all modules are set up and in working order, notwithstanding persistent Bluetooth issues. Instating two simple linear controllers for the balance in both dimensions is only a matter of a few lines of code and some ball-park estimates of inertias and motor parameters. I’m hoping I can do this while I’m still on leave from my agonizingly demotivating day job.

Sneak peek:

  while(1)
  {
    // get time since last update
    dt = TMR_dt();

    // base wheel
    bwheel_pos_old = bwheel_pos_new;
    bwheel_pos_new = POS2CNT;
    bwheel_vel = ((bwheel_pos_new - bwheel_pos_old)/90112)/dt*60;    // 90112cpr with x4 quadrature after gearbox

    // inertia wheel
    iwheel_pos_old = iwheel_pos_new;
    iwheel_pos_new = POS1CNT;
    iwheel_vel = ((iwheel_pos_new - iwheel_pos_old)/260)/dt*60;    // 260cpr with x4 quadrature
    
    // IMU roll calculations
		accel_roll_angle = IMU_Accel_Roll();               // roll angle from accelerometer
    kal_roll_angle = IMU_Kal_TimeVariantSoln(&kal_roll_data, dt, IMU_Gyro_Roll(), accel_roll_angle);
    kal_roll_rate = kal_roll_data.rate;
    
    // IMU pitch calculations
    accel_pitch_angle = IMU_Accel_Pitch();               // pitch angle from accelerometer
    kal_pitch_angle = IMU_Kal_TimeVariantSoln(&kal_pitch_data, dt, IMU_Gyro_Pitch(), accel_pitch_angle);
    kal_pitch_rate = kal_pitch_data.rate;
    
    // Safety functionality
    if (  kal_roll_angle > 30.0*3.1415926/180.0 || kal_roll_angle < -30.0*3.1415926/180.0 \
          || kal_pitch_angle > 30.0*3.1415926/180.0 || kal_pitch_angle < -30.0*3.1415926/180.0 )
    {
      PWM_Mtr1brake();
      PWM_Mtr2brake();
    }

    ...

I’m eagerly awaiting a symbolic ‘Hello, World!’ breakthrough. It won’t be long now…