📄 car.c
字号:
//*****************************************************************************
//
// car.c - Code for running the LM3S316 car.
//
// Copyright (c) 2005-2007 Luminary Micro, Inc. All rights reserved.
//
// Software License Agreement
//
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
//
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws. All rights are reserved. Any use in violation
// of the foregoing restrictions may subject the user to criminal sanctions
// under applicable laws, as well as to civil liability for the breach of the
// terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 199 of an01245.
//
//*****************************************************************************
#include "../../hw_sysctl.h"
#include "../../hw_types.h"
#include "car.h"
#include "compiler.h"
#include "lights.h"
#include "motors.h"
#include "random.h"
#include "sensors.h"
#include "switches.h"
#include "system.h"
//*****************************************************************************
//
//! \page car_intro Introduction
//!
//! The car application builds upon the framework provided by the drivers for
//! the various components of the car, such as the motors, lights, sensors,
//! etc. It takes stimulus from inputs (such as the sensors) and determines
//! the reaction to be applied via the outputs (such as the motors).
//!
//! When the car is moving, there are four major behaviors that are utilized:
//!
//! - When the car does not see any obstacles, or there are no obstacles close
//! enough for the car to care about, then it will simply drive forward.
//!
//! - When the car sees that an obstacle is too close, it will turn away from
//! the obstacle, while still generally driving forward, to avoid colliding
//! with it.
//!
//! - When the car sees that it appears to be parallel to an obstacle and close
//! enough to it, it will make minor directional adjustments, but typically
//! drive forward, in order to attempt to follow the obstacle.
//!
//! - When the car sees that it is too close to an obstacle, or when the random
//! event timeout has occurred, it will simply spin in place until it has
//! found a direction that it can safely proceed.
//!
//! The decision making process consists of deciding which of these behaviors
//! should be utilized based on the current environment (with a valid choice
//! being to continue with the current behavior) and then applying the chosen
//! behavior to the car. Some behaviors (driving forward or spinning in place)
//! are absolute behaviors; they do not take the environment into account when
//! determining how to drive the motors. Other behaviors (avoiding obstacles
//! and following obstacles) do take the environment into account when
//! determining how to drive the motors; these behaviors have many different
//! end drive state for the car that are all lumped into the same basic
//! behavior (i.e. slowly turning away from an obstacle that is far away vs.
//! quickly turning away from an obstacle that is close is still turning to
//! avoid an obstacle).
//!
//! In addition to driving the car around, a diagnostic mode is provided. This
//! mode allows the hardware pieces to be checked out one at a time, both to
//! diagnose a hardware problem (i.e. a burned out LED) and to diagnose a
//! connection problem (i.e. the left and right sensors being swapped). The
//! steps of diagnostic mode are as follows (in order):
//!
//! - The first step turns on all of the LEDs and leaves all of the motors
//! stopped. This is useful for taking pictures of the car with the lights
//! on.
//!
//! - The next step drives the left motors in the forward direction, and blinks
//! the left headlight. This checks to see if the left motors can be driven
//! in the forward direction and that the left headlight can be correctly
//! driven.
//!
//! - The next step drives the left motors in the backward direction, and
//! blinks the left tail light. This checks to see if the left motors can be
//! driven in the backward direction and that the left tail light can be
//! correctly driven.
//!
//! - The next step drives the right motors in the forward direction, and
//! blinks the right headlight. This checks to see if the right motors can
//! be driven in the forward direction and that the right headlight can be
//! correctly driven.
//!
//! - The next step drives the right motors in the backward direction, and
//! blinks the right tail light. This checks to see if the right motors can
//! be driven in the backward direction and that the right tail light can be
//! correctly driven.
//!
//! - The next step drives all the motors in the reverse direction at a speed
//! proportional to the analog reading from the left sensor. This checks to
//! see if the left sensor is returning valid data.
//!
//! - The next step is the same as the previous, only using the analog reading
//! from the right sensor. This checks to see if the right sensor is
//! returning valid data.
//!
//! - The final step is the same as the previous, only using the analog reading
//! from the center sensor. This checks to see if the front sensor is
//! returning valid data.
//!
//! The code for the car application is conatined in <tt>car.c</tt>, with
//! <tt>car.h</tt> containing the API definitions for use by the remainder of
//! the application.
//
//*****************************************************************************
//*****************************************************************************
//
//! \defgroup car_api Definitions
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
//! Set the motor speed limit based on the table size. The motor limit is the
//! maximum deviation from a 50/50 drive of the left/right motors. To drive
//! forward, the left and right motors are driven at a 50% duty cycle. Turning
//! takes duty cycle from one motor and provides it to the other motor; for
//! example 60/40. The motor speed limit is the maximum amount that can be
//! taken from one motor and given to the other.
//
//*****************************************************************************
#ifdef BIG_TABLE
#define MOTOR_LIMIT 50
#else
#define MOTOR_LIMIT 15
#endif
//*****************************************************************************
//
//! Converts inches into a fixed point representation.
//!
//! \param i is the number of inches.
//! \param f is the number of thousanths of an inch.
//!
//! This will convert a distance specified in inches and thousanths of an inch
//! into the fixed point representation used for distances. In this case, 1024
//! is one inch, making for fast division in many cases (by simply shifting);
//! the maximum distance representable by a short signed integer is therefore
//! ~32.5 inches (~82.5 cm).
//!
//! \return Returns the fixed point representation for the given distance.
//
//*****************************************************************************
#define INCHES(i, f) (((i) * 1024) + (((f) * 1024) / 1000))
//*****************************************************************************
//
//! A large value to represent an "infinite" distance. This is used when the
//! sensor does not detect any obstacle within its range of operation.
//
//*****************************************************************************
#define INFINITY INCHES(30, 0)
//*****************************************************************************
//
//! Converts motor speed percentage into a fixed point representation.
//!
//! \param p is the motor speed percentage.
//!
//! This will convert a motor speed percentage specified in whole percent into
//! a fixed point representation used for motor speed. In this case, 256 is
//! one percent, making for fast division in many cases (by simply shifting).
//!
//! \return Returns the fixed point representation for the given motor speed.
//
//*****************************************************************************
#define SPEED(p) ((p) * 256)
//*****************************************************************************
//
//! The amount of time the car will be alowed to roam before it makes a random
//! turn. The value chosen is based on a random number and is scaled based on
//! the size of the table in use (on a big table, the car should be allowed to
//! roam longer before a random turn so it has more opportunity to explore).
//
//*****************************************************************************
#ifdef BIG_TABLE
#define RANDOM_TIME (((unsigned long)RandomNumber() >> 24) + 300)
#else
#define RANDOM_TIME (((unsigned long)RandomNumber() >> 25) + 150)
#endif
//*****************************************************************************
//
//! This describes the various states in the the car's state machine.
//
//*****************************************************************************
typedef enum
{
//
//! The car is not moving and not reacting to its environment. Based on
//! user input, the car will transition to either #MODE_IN_OPEN or
//! #MODE_DIAG1.
//
MODE_STOP = 0,
//
//! The car is in the process of stopping due to a user input request.
//! The car will remain in this state until the push button is released, at
//! which point the car will automatically transition to #MODE_STOP.
//
MODE_STOPPING,
//
//! The car is driving around in the open. There are either no walls
//! visible or no walls close enough to be concerned about. Based on the
//! distance to walls, the car will transition to #MODE_APPROACHING,
//! #MODE_TURN_LEFT, or #MODE_TURN_RIGHT. Based on expiration of the
//! random timer, the car will transition to either #MODE_RANDOM_LEFT or
//! #MODE_RANDOM_RIGHT. Based on user input, the car will transition to
//! #MODE_STOPPING.
//
MODE_IN_OPEN,
//
//! The car is approaching a wall and taking measures to avoid colliding
//! with it. Bsaed on the distance to walls, the car will transition to
//! #MODE_IN_OPEN, #MODE_FOLLOWING, #MODE_TURN_LEFT, or #MODE_TURN_RIGHT.
//! Based on expiration of the random timer, the car will transition to
//! either #MODE_RANDOM_LEFT or #MODE_RANDOM_RIGHT. Based on user input,
//! the car will transition to #MODE_STOPPING.
//
MODE_APPROACHING,
//
//! The car is driving parallel to a wall on its left or right and is
//! taking measures to remain parallel to it. Based on the distance to
//! walls, the car will transition to #MODE_IN_OPEN, #MODE_APPROACHING,
//! #MODE_TURN_LEFT, or #MODE_TURN_RIGHT. Based on expiration of the
//! random timer, the car will transition to either #MODE_RANDOM_LEFT or
//! #MODE_RANDOM_RIGHT. Based on user input, the car will transition to
//! #MODE_STOPPING.
//
MODE_FOLLOWING,
//
//! The car is transitioning from driving forward to an in-place turn to
//! the left. Once the speed of the motors have ramped down to zero, the
//! car will automatically transition to #MODE_TURNING.
//
MODE_TURN_LEFT,
//
//! The car is transitioning from driving forward to an in-place turn to
//! the right. Once the speed of the motors have ramped down to zero, the
//! car will automatically transition to #MODE_TURNING.
//
MODE_TURN_RIGHT,
//
//! The car is turning in place, either to the left (i.e. counter-
//! clockwise) or to the right (i.e. clockwise). Based on the distance to
//! walls, the car will transition to #MODE_FORWARD. Based on user input,
//! the car will transition to #MODE_STOPPING.
//
MODE_TURNING,
//
//! The car is transitioning from turning in place to driving forward.
//! Once the speed of the motors have ramped down to zero, the car will
//! automatically transition to #MODE_APPROACHING.
//
MODE_FORWARD,
//
//! The car is transitioning from driving forward to an in-place turn to
//! the left as a result of the random timer expiring. Once the speed of
//! the motors have ramped down to zero, the car will automatically
//! transition to #MODE_RANDOM_TURN.
//
MODE_RANDOM_LEFT,
//
//! The car is transitioning from driving forward to an in-place turn to
//! the right as a result of the random timer expiring. Once the speed of
//! the motors have ramped down to zero, the car will automatically
//! transition to #MODE_RANDOM_TURN.
//
MODE_RANDOM_RIGHT,
//
//! The car is turning in place, either to the left (i.e. counte-
//! clockwise) or to the right (i.e. clockwise) as a result of the random
//! timer expiring. Based on the distance to walls, the car will
//! transition to #MODE_RANDOM_FORWARD. Based on user input, the car will
//! transition to #MODE_STOPPING.
//
MODE_RANDOM_TURN,
//
//! The car is transitioning from turning in place as a result of the
//! random timer expiring to driving forward. Once the speed of the motors
//! have ramped down to zero, the car will automatically transition to
//! #MODE_APPROACHING.
//
MODE_RANDOM_FORWARD,
//
//! The car is in step one of diagnostic mode, known as "head-shot" mode.
//! All the motors will be turned off and the headlights and tail lights
//! will be turned on. Based on user input, the car will transition to
//! #MODE_DIAG2.
//
MODE_DIAG1,
//
//! The car is in step two of diagnostic mode. The left motors will spin
//! in the forward direction and the left headlight will blink in a series
//! of two blinks (with a two second pause between). Based on user input,
//! the car will transition to #MODE_DIAG3.
//
MODE_DIAG2,
//
//! The car is in step three of diagnostic mode. The left motors will spin
//! in the backward direction and the left tail light will blink in a
//! series of three blinks (with a two second pause between). Based on
//! user input, the car will transition to #MODE_DIAG4.
//
MODE_DIAG3,
//
//! The car is in step four of diagnostic mode. The right motors will spin
//! in the forward direction adn teh right headlight will blink in a series
//! of four blinks (with a two second pause between). Based on user input,
//! the car will transition to #MODE_DIAG5.
//
MODE_DIAG4,
//
//! The car is in step five of diagnostic mode. The right motors will spin
//! in the backward direction and the right tail light will blink in a
//! series of five blinks (with a two second pause between). Based on user
//! input, the car will transition to #MODE_DIAG6.
//
MODE_DIAG5,
//
//! The car is in step six of diagnostic mode. All motors will spin in the
//! backward direction at a speed proportional to the left sensor reading
//! and all headlights and tail lights will blink in a series of six blinks
//! (with a two second pause between). Based on user input, the car will
//! transition to #MODE_DIAG7.
//
MODE_DIAG6,
//
//! The car is in step seven of diagnostic mode. All motors will spin in
//! the backward direction at a speed proportional to the right sensor
//! reading and all headlights and tail lights will blink in a series of
//! seven blinks (with a two second pause between). Based on user input,
//! the car will transition to #MODE_DIAG8.
//
MODE_DIAG7,
//
//! The car is in step eight of diagnostic mode. All motors will spin in
//! the backward direction at a speed proportional to the center sensor
//! reading and all headlights and tail lights will blink in a series of
//! eight blinks (with a two second pause between). Based on user input,
//! the car will transition to #MODE_STOP.
//
MODE_DIAG8
}
tCarMode;
//*****************************************************************************
//
//! The current mode of operation.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -