AME 3623: Project 8: Compasses and Position Control
For this project, you will be writing a control loop that orients the
craft to a desired heading.
- All components of the project are due by Tuesday, April 20th
at 5:00pm
- Groups are the same as for project 1.
- Discussion within groups is fine.
- Discussion across groups may not be about the specifics of the
solution (general programming/circuit issues are fine to
discuss).
At the end of this project, you should be able to:
- extract hovercraft orientation from a magnetometer sensor,
- use the sensory data to drive the motors in such a way that the
craft will orient toward a goal, and
- achieve that goal without substantial oscillation.
Inertial Measurement Units
Our 9-axis inertial measurement units (IMUs) are composed of a 3-axis
linear accelerometer, a 3-axis rate gyroscope, and a 3-axis
magnetometer. The accelerometer and gyroscope are simple to
calibrate automatically (this is done at power-up). However, because
the earth's magnetic field varies depending on where you are located,
we must perform a full calibration process in situ. This is done by
taking a set of samples from the magnetometer as it is rotated over
the full range of orientations that we are interested in.
The IMU library provides the following functions (two of which you already have used):
- imu_setup() initializes the inertial measurement
unit. This setup function makes a reasonable guess about your
magnetometer biases. However, these may or may not work well
for your configuration.
- imu_update() updates the state of the inertial
measurement unit. This function expects to be called regularly
(at 100-200 Hz).
- imu_calibrate_magbias() is a function that will walk
you through the steps of calibrating your compass.
Specifically:
- It will ask you to turn your craft slowly (at a near
constant speed). The function expects that you will
complete four full revolutions in 40 seconds.
- After execution of this function, the magnetometer
biases will be reset. This function also prints out 3
lines of code that you can place into your setup() function. By
including this code, you don't have to call
imu_calibrate_magbias() every time you start your program.
- NOTE: make sure to initialize your serial port before calling this function.
Component 1: Circuit
There are no changes to be made to your circuit.
Component 2: Compass Software and Configuration
- Update your imu_step() function:
- It still calls imu_update()
- If a character has been received from the serial input:
- If that character is 'c', then this function should
call imu_calibrate_magbias()
- If that character is 'g', then this function should set the
heading_goal (a global float variable) to
the craft's current orientation.
- The report_step() function should print
out the current state of IMU.yaw
- After calibration, test your compass:
- Orient your craft such that the compass is reporting
zero degrees.
- Turn your craft by 90 degrees. The reported compass
heading should be within about ~5 degrees of 90 degrees.
- Repeat for the other cardinal directions.
- If all four headings are reported correctly, then you
have a reasonable calibration of your compass and you
are done. Make sure that your new magnetometer
biases are set in your setup() function (that imu_calibrate_magbiases()
printed out).
- If the headings are not reasonable, then repeat the
calibration process.
Component 3: Control Software
Implement the following functions:
- float compute_error(float theta,
float heading_goal) returns the difference between the goal and
the current heading.
Specifically, we are asking what the orientation of the goal
is relative to a coordinate frame that is defined by the hovercraft.
Return values must range between -180.0 and 180.0 degrees. Positive
values correspond to the current orientation being clockwise from
the goal.
You may assume that the input parameters are in the range of +/-180 degrees
- float db_clip(float error, float deadband, float
saturation) takes as input an orientation error, a deadband
level and a saturation level, and returns a modified error.
- For an error that is +/- deadband, this function returns a
zero.
- For an error that is larger than saturation, this function
returns saturation - deadband
- For an error between deadband and
saturation, the return value linearly increases
with increasing error (gain=1).
- and you must deal with the negative side, too.
- Note: this function must be continuous.
- Your pd_step() function should remain the same as
in project 5, with the following change:
float fx = 0.0;
float fy = 0.0;
float heading_error = ...
float modified_error = ...
float torque = Kp * modified_error;
set_forces(fx, fy, torque);
where modified_error has already been subjected to the deadband
and saturation
Component 4: Finite State Machine
Reuse your finite state machine from the prior project.
Component 5: Testing
- Slowly increase Kp until the craft
tries to maintain the goal orientation. Holding on to your
craft during this stage, simulating rotations by hand, is a
good first step in testing.
- After initial testing, you can place the craft on the floor (or a
table, if you are careful).
- The craft should produce a thrust in the direction that is the
shortest distance to the goal (switching direction at 180 degrees behind
the goal)
- We do not expect the craft to precisely stop at the goal.
Instead, it will oscillate around the goal (this is okay for now - we will fix it soon).
Component 6: Proportional-Derivative Control
Re-introduce the damping term to your control law. Slowly increase Kd
until your craft is approximately critically damped.
What to Hand In
All components of the project are due by Tuesday, April 20th at
5:00 pm.
- Demonstration/Code Review: All group
members must be present. The demonstration must be completed
by Friday, April 23rd.
- Check in the following to your project 6 area of your
subversion tree:
- Personal report: there is no personal report for this project.
Grading
Project lead credit:
- Each person must be the primary integrator of circuits and code
for two projects over the course of the semester.
For a successful project, we expect:
- A properly configured circuit
- IMU is properly connected to your processor
- Properly written software
- imu_step()
- pd_step()
- report_step()
- Finite State Machine implementation
- IMU Calibration: the compass of the IMU is properly calibrated.
- Properly documented code
- Project-level documentation at the top of the ino file:
name and group number, date and project number
- Function-level documentation above the function
definition. Include an abstract description of what the
function does; a list of the names, types and units
associated with each parameter and return value; and the
effects that the function has on the processor or
connected components.
- In-line documentation inside of functions: individual
lines or small groups of lines have an English
description that describes logically what the code is doing
andrewhfagg -- gmail.com
Last modified: Fri Apr 16 12:22:19 2021