AME 3623: Project 3
- All components of the project are due by Thursday, March 1st.
at 1:30 am
- Groups are the same as for project 1.
- Discussion within groups is fine.
- Discussion across groups may not be about the specifics of the
project solution (general programming/circuit issues are fine to
discuss).
For this project, you will be reading "image slip" data from a set of
cameras and estimating the distance traveled by the hovercraft in a
given period of time. A key part of this project will be the
construction of a mathematical model that captures this relationship.
This model will allow us, in the long run, to estimate the velocity of
the hovercraft in a coordinate frame centered on the craft.
Each group will be issued: a hovercraft, equipped with a power
conditioning system and three downward
looking cameras.
At the end of this project, you should be able to:
- connect a digital sensor to your microcontroller,
- read digital data into your microcontroller
- display information through a USB serial interface,
- design mathematical models for transforming raw sensor data into calibrated information,
- implement these models in code, and
- test the models.
Component 1: Microcontroller Circuit
Your hovercraft is equipped with power circuit and three
downward-looking cameras. When turned on, the power circuit delivers
+5V to the top deck (where your circuit will be located) and to the
red LEDs that are part of the camera system.
Power
- The Ground line (black) must be connected into your ground bus.
- The +5V line may be used to power your Teensy (via the Vin pin). However, until
a modification is made to your Teensy, never connect both
the +5V line to your Teensy while it is plugged into the USB
port of your computer (doing so may result in damage to
your computer).
After the modification, connecting the Teensy to your computer
will allow communication, but will no longer power the Teensy.
Hence, you must rely on the power system.
Cameras
The CJMCU-110 Optical Flow Camera pin-outs are shown below:
The common lines that are shared across all cameras (and should be
connected together) are:
- Black: Ground
- Red: +5V Power
- Blue: MISO (Arduino pin 12)
- Orange: MOSI (Arduino pin 11)
- Green: SCL (Arduino pin 13)
- Gray: Reset (choose an unused digital pin)
In addition, each camera has its own Yellow line that is used to select
the camera for communication. Each camera must have a unique digital
output pin assigned to it.
Component 2: Camera Interface Software for Data Collection
Create a new project in your Arduino environment; copy over the code
that you have developed so far.
The OpticalFlowCamera.zip library is in the lib
directory of your Dropbox. Within the Arduino environment, select
Sketch menu / Include Library / Add .ZIP Library. Navigate to
and select OpticalFlowCamera.zip. You will not need to repeat
this step in the future.
Write a data collection program:
- Define the camera interface pins at the top of your INO file.
For example, the following code defines the select pins for
cameras 1, 2 and 3 as Arduino pins 8, 7 and 10, and the reset pin as
pin 9.
////////////////////////////////////////////////////
// Global constants
// Total number of cameras
const int NUM_CAMERAS = 3;
// Select pins for the 3 cameras
const uint8_t CAMERA_SELECT[NUM_CAMERAS] = {8, 7, 10};
// Common reset pin
const uint8_t RESET_PIN = 9;
- Also in the global space, create and configure a new object for
interfacing to the camera system:
/////////////////////////////////////////////////////
// Global variables
// Camera interface object
OpticalFlowCamera cameras(RESET_PIN);
- In setup(), initialize the serial port connected to the USB port (which is
connected to your computer):
Serial.begin(57600);
- Also in setup(), initialize each of the cameras. For example, the following
code will configure and initialize camera 2 (index 1 in the array):
int ret = cameras.addCamera(CAMERA_SELECT[1]);
Here, you explicitly declare pin 7 as being the select line for
this particular camera. This function returns a zero (0) if
the camera was properly detected and initialized. If a zero is not returned, then your code should
print an error and stop. See the
OpticalFlowCamera.cpp file for more details (inside of the ZIP file).
- Implement the following function:
void accumulate_slip(int32_t adx[3], int32_t ady[3])
This function will query each of the cameras for
its slip and image quality measures. For example:
int8_t dx, dy;
uint8_t quality;
int result = cameras.readSlip(CAMERA_SELECT[1], dx, dy, quality);
will query camera 2 (index 1) for its X and Y slip and image
quality. This function returns a status code. When this
status code is zero, the variables dx, dy and quality are
changed by this function call to reflect the slip since the
last time the camera was queried. This changing of the input
variable values is a feature provided by C++ (and is a new
feature from what you are used to in C).
If the status code is -1, this indicates an overflow (because
dx/dy can only encode pixel changes of -128 ... 127).
If this error does occur, then your function should alert you to the problem.
In this
situation, increase the rate at which you are querying the camera.
If the status code is -2, this indicates that no slip has been
detected (e.g., the hovercraft has not moved). In this case,
dx/dy/quality should not be used (it is safe to assume that
dx=dy=0).
Your function should accumulate (sum) the slip values using the adx/ady parameters.
Note that in C, arrays are pass-by-value (changes to the individual array elements
will be visible in the calling function).
- In loop():
- Call accumulate_slip()
- Delay for some fixed period (start with 50ms).
- Every ~10 times through the loop, print out the accumulated values.
- Check for serial input. If a
character c is received, then the accumulated values
should be reset to zero. Note that this must be non-blocking
so that you will continue to query your cameras if no
characters have arrived.
Component 3: Data Collection
- We have set up a test field in FH 300. This board has a
distance of one meter marked on it.
- Place your hovercraft chassis at the start line, facing
forward on the craft to the end line (we will call this the +X
direction). Clear
the accumulated values. Slowly move your craft to the
end line (do not rotate the craft). Record the accumulated values (6 values in total) in
the following order: camera 1 dx/dy, camera 2 dx/dy and camera 3
dx/dy. In three separate columns, record a movement along the X
direction of one meter, a movement along the Y direction of
zero meters and a rotation of zero radians (i.e., these columns
should be 1, 0, 0).
- Repeat this process 10 times.
- Place your hovercraft chassis at the start line, facing with
its left side to the end line (we will call this the +Y
direction). Perform the same procedure as above, while moving
the craft one meter to its left. Record the accumulated
values, adding three more columns: 0, 1, 0.
- Repeat this process 10 times.
- Place your hovercraft chassis anywhere on the board. Clear the
accumulated values. Rotate the chassis by one full rotation
without translating the center of the chassis.
Record the accumulated values, adding three more columns: 0, 0,
360 (degrees)
Component 4: Sensor Model
The result of your data collection process is a matrix of 30 rows and
6 columns, representing the accumulated slip measured by each camera
for 30 different cases. This matrix is appended to another matrix of
30 rows and 3 columns, representing the movement of the chassis along
X, Y and theta. We will use multi-regression to derive a linear function
from the accumulated slip values to the chassis movement values.
Specifically, we wish to solve for functions of the following form:
X = a0 + a1 * adx1 + a2 * ady1 + a3 * adx2 + a4 * ady2 + a5 * adx3 + a6 * ady3
where a0 ... a6 are the coefficients of our function, adx?/ady? are
the accumulated slip values for the x and y directions for each
camera, and X is the motion along the chassis' X direction. Note that we
will have corresponding functions (and coefficients) for Y and theta.
See the instructions
for performing multi-regression in Excel.
See the instructions
for configuring Excel for regression if you have not yet used
Excel to perform regression tasks.
In the Summary Output from the regression process, you will
find a column labeled Coefficients. These are the parameters of
the linear model that result from the regression process (a0 ... a6)
from above.
Component 5: Implement the Model
Implement a function of the form:
void compute_chassis_motion(int32_t adx[3], int32_t ady[3], float[3] motion);
where adx and ady are arrays representing the accumulated slip values
from each of the cameras, and motion is an array representing the
motion along X, Y and theta, respectively. This function will take as
input adx and ady, and fill in the values for the motion array. The
motion values are in units of meters, meters, and degees,
respectively. Note
that when you pass an array to a function in C, you are passing the
memory location for the array (and not the array values themselves).
Hence, any change to motion by this function will be visible to the
calling function.
Component 6: Testing
-
Modify your camera interface function to also report X, Y and theta on
the same line as the raw slip values.
- For each of the same movements used during data collection,
record the reported X/Y/theta motion.
- Repeat each five times.
- Report in graphical form the mean and standard deviation of the
X/Y/theta (for a total of 9 different means/standard deviations)
What to Hand In
Submit to your project3 folder of your subversion tree by
Tuesday, March 6th at 5pm:
- Documented code. The documentation requirements are
the same as in project 1.
- Raw data: include the Excel spreadsheet containing your
raw data and the fit model parameters.
- Figures: your test results (JPG, PNG, PDF or EPS format).
Other components:
- Demonstration/Code Review: All group
members must be present. This review must be completed by Friday,
March 9th. However, it is better to complete these reviews
as early as possible.
- Personal report: a survey will be issued through Catme.
These surveys must be completed in order to receive a grade for
this project.
Grading
-
Personal programming credit: this project offers one programming credit.
-
Group grade distribution:
- 35%: Project implementation
- 30%: Demonstration of working project (to either
of the TA or the instructor)
- 35%: Code documentation
-
Group Grading Rubric
-
Grades for individuals will be based on the group grade, but weighted
by the assessed contributions of the group members to the non-personal programming items.
andrewhfagg -- gmail.com
Last modified: Tue Feb 27 02:00:28 2018