Hardware components | ||||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
| ||||||
|
We developed and programmed a robot capable of automatically rotating its camera or fixing it at a specific angle. The robot can be remotely controlled using LabView, allowing users to manipulate its operations. Additionally, it can be programmed to navigate toward a wall and scan for obstacles in its path. The robot maps the precise shape of detected obstacles and displays the results in real time on LabView.
The robot is powered by a TI F28379D Launchpad board, which controls all of its movements. The F28379D drives two motors using PWM signals to operate the robot's wheels. The robot is equipped with two infrared sensors: one mounted at the front and another on top. The top sensor is attached to a servomotor, allowing it to rotate at specific angles to scan the surrounding area and identify the position of obstacles. This enables the robot to determine the general shape of obstacles, which is visualized in the final output.
Additionally, the top sensor can be fixed at a 45-degree angle, enabling the robot to scan along a wall. While navigating, the robot makes continuous left turns to follow the wall’s contour. The infrared sensor transmits data to the F28379D through an ADC, and the obstacle's real-time shape is displayed in LabView for analysis.
Fix Point ScanningIn this section, we place two squares within a designated area and define 10 distinct points around the region, each with a unique bearing angle, x_ref, and y_ref values. Using LabView, the robot can be programmed to navigate through each of these points. At each position, the robot can be instructed to stop and initiate a scanning process. The following two videos demonstrate the sensor's behavior when the robot stops and illustrate how the final results are visualized in LabView.
Wall Following ScanningIn this section, we introduce a wall-following scanning process where the robot is programmed to follow the contours of a wall while simultaneously conducting a scan. The robot continuously adjusts its movement along the wall, while a sensor collects data and generates a scan of the surrounding environment. As the robot navigates along the wall, the sensor's readings are transmitted to LabView, which processes and visualizes the data in real-time. The scanning data is plotted dynamically, providing a continuous representation of the robot’s surroundings. The following additional videos demonstrate the robot's ability to follow the wall while scanning and how the resulting data is plotted and visualized within LabView.
Finalproject_fixed_position.c
C/C++//#############################################################################
// FILE: LAB6starter_main.c
//
// TITLE: Lab Starter
//#############################################################################
// Included Files
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <limits.h>
#include "F28x_Project.h"
#include "driverlib.h"
#include "device.h"
#include "F28379dSerial.h"
#include "LEDPatterns.h"
#include "song.h"
#include "dsp.h"
#include "fpu32/fpu_rfft.h"
#define PI 3.1415926535897932384626433832795
#define TWOPI 6.283185307179586476925286766559
#define HALFPI 1.5707963267948966192313216916398
// The Launchpad's CPU Frequency set to 200 you should not change this value
#define LAUNCHPAD_CPU_FREQUENCY 200
// ----- code for CAN start here -----
#include "F28379dCAN.h"
//#define TX_MSG_DATA_LENGTH 4
//#define TX_MSG_OBJ_ID 0 //transmit
#define RX_MSG_DATA_LENGTH 8
#define RX_MSG_OBJ_ID_1 1 //measurement from sensor 1
#define RX_MSG_OBJ_ID_2 2 //measurement from sensor 2
#define RX_MSG_OBJ_ID_3 3 //quality from sensor 1
#define RX_MSG_OBJ_ID_4 4 //quality from sensor 2
// ----- code for CAN end here -----
// Interrupt Service Routines predefinition
__interrupt void cpu_timer0_isr(void);
__interrupt void cpu_timer1_isr(void);
__interrupt void cpu_timer2_isr(void);
__interrupt void SWI_isr(void);
// ----- code for CAN start here -----
__interrupt void can_isr(void);
// ----- code for CAN end here -----
__interrupt void SPIB_isr(void);
void setupSpib(void);
// JW: ----- code for motor reading ------
void init_eQEPs(void);
// JW: ----- float for left motor recording ------
float readEncLeft(void);
// JW: ----- float for right motor recording ------
float readEncRight(void);
// JW: ----- float for the radius of left motor ------
float LeftWheel = 0;
// JW: ----- float for the radius of Right motor ------
float RightWheel = 0;
// JW: ----- float for the left wheel travel distance ----
float LeftDistance = 0;
float LeftDistance1 = 0;
// JW: ----- float for the Right wheel travel distance ----
float RightDistance = 0;
float RightDistance1 = 0;
// JW: ------call the EPWM2A and 2B -----
void setEPWM2A(float controleffort);
void setEPWM2B(float controleffort);
// predefinition for the servo control functions
void start_scan(int start);
void setEPWM8A_RCServo(float angle);
// JW: ------call the ULeft and URight -----
float ULeft = 5.0;
float URight = 5.0;
// ------call the VLeft and VRight -----
float VRight = 0;
float VLeft = 0;
// JW: -----Setup value for PI controller Exercise 3------
float eKLeft = 0;
float eKLeft1 = 0;
float IKLeft = 0;
float IKLeft1 = 0;
float uKLeft = 0;
float eKRight = 0;
float eKRight1 = 0;
float IKRight = 0;
float IKRight1 = 0;
float uKRight = 0;
//Servo scan variable
int16_t start = 0;
float servo_angle = 0;
float dist_servo = 0;
int16_t updown = 1;
float xR_servo = 0;
float yR_servo = 0;
float Kp = 3.0;
float Ki = 25.0;
float Vref = 0;
//JW: -----Setup turn error for PI controller Exercise 4------
float eturn = 0;
float turn = 0;
float Kpturn = 3;
//JW: -----The code copy and paste from Lab6 exercise 5------
float printLV3 = 0;
float printLV4 = 0;
float printLV5 = 0;
float printLV6 = 0;
float printLV7 = 0;
float printLV8 = 0;
float x = 0;
float y = 0;
float bearing = 0;
extern uint16_t NewLVData;
extern float fromLVvalues[LVNUM_TOFROM_FLOATS];
extern LVSendFloats_t DataToLabView;
extern char LVsenddata[LVNUM_TOFROM_FLOATS*4+2];
extern uint16_t newLinuxCommands;
extern float LinuxCommands[CMDNUM_FROM_FLOATS];
uint32_t numTimer1calls = 0;
//JW: -----Defined the variable for Lab6 exercise 6------
// Robot Width
float Wr = 0.173;
// Radius Wheel
float Rwh = 0.06;
//Wheel Rotation Angle
float thetaL = 0;
float thetaL1 = 0;
float dotthetaL = 0;
float thetaR = 0;
float thetaR1 = 0;
float dotthetaR = 0;
float thetaAvg = 0;
float dotthetaAvg = 0;
//Robot Pose X Y coordinate
float xR = 0;
float xR_1 = 0;
float dotxR = 0;
float yR =0;
float yR_1 =0;
float dotyR =0;
// Robot Pose Angle or Bearing
float phiR = 0;
//JW: -----Defined the variable for Lab6 exercise 7------
float Kpright = 0.001;
float Kpfront = 0.0002;
float ref_right = 300.0;
float ref_front = 1400.0;
float ref_left = 1400.0;
float distright = 0.0;
float distfront = 0.0;
float distleft = 0.0;
uint16_t RWF = 1;
uint16_t LWF = 1;
// Count variables
uint32_t numTimer0calls = 0;
uint32_t numSWIcalls = 0;
extern uint32_t numRXA;
uint16_t UARTPrint = 0;
uint16_t LEDdisplaynum = 0;
int16_t accelx_raw = 0;
int16_t accely_raw = 0;
int16_t accelz_raw = 0;
int16_t gyrox_raw = 0;
int16_t gyroy_raw = 0;
int16_t gyroz_raw = 0;
float accelx = 0;
float accely = 0;
float accelz = 0;
float gyrox = 0;
float gyroy = 0;
float gyroz = 0;
int32_t SpibNumCalls = 0;
// ----- code for CAN start here -----
// volatile uint32_t txMsgCount = 0;
// extern uint16_t txMsgData[4];
volatile uint32_t rxMsgCount_1 = 0;
volatile uint32_t rxMsgCount_3 = 0;
extern uint16_t rxMsgData[8];
uint32_t dis_raw_1[2];
uint32_t dis_raw_3[2];
uint32_t dis_1 = 0;
uint32_t dis_3 = 0;
uint32_t quality_raw_1[4];
uint32_t quality_raw_3[4];
float quality_1 = 0.0;
float quality_3 = 0.0;
uint32_t lightlevel_raw_1[4];
uint32_t lightlevel_raw_3[4];
float lightlevel_1 = 0.0;
float lightlevel_3 = 0.0;
// manual input values:
float xrreal = 0.0;
float yrreal = 0.0;
float bearingreal = 0.0;
uint16_t point = 0;
uint32_t measure_status_1 = 0;
uint32_t measure_status_3 = 0;
volatile uint32_t errorFlag = 0;
// ----- code for CAN end here -----
void main(void)
{
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
InitSysCtrl();
InitGpio();
// Blue LED on LaunchPad
GPIO_SetupPinMux(31, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(31, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO31 = 1;
// Red LED on LaunchPad
GPIO_SetupPinMux(34, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(34, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPBSET.bit.GPIO34 = 1;
// LED1 and PWM Pin
GPIO_SetupPinMux(22, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(22, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPACLEAR.bit.GPIO22 = 1;
// LED2
GPIO_SetupPinMux(94, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(94, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPCCLEAR.bit.GPIO94 = 1;
// LED3
GPIO_SetupPinMux(95, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(95, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPCCLEAR.bit.GPIO95 = 1;
// LED4
GPIO_SetupPinMux(97, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(97, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPDCLEAR.bit.GPIO97 = 1;
// LED5
GPIO_SetupPinMux(111, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(111, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPDCLEAR.bit.GPIO111 = 1;
// LED6
GPIO_SetupPinMux(130, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(130, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPECLEAR.bit.GPIO130 = 1;
// LED7
GPIO_SetupPinMux(131, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(131, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPECLEAR.bit.GPIO131 = 1;
// LED8
GPIO_SetupPinMux(25, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(25, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPACLEAR.bit.GPIO25 = 1;
// LED9
GPIO_SetupPinMux(26, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(26, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPACLEAR.bit.GPIO26 = 1;
// LED10
GPIO_SetupPinMux(27, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(27, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPACLEAR.bit.GPIO27 = 1;
// LED11
GPIO_SetupPinMux(60, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(60, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPBCLEAR.bit.GPIO60 = 1;
// LED12
GPIO_SetupPinMux(61, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(61, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1;
// LED13
GPIO_SetupPinMux(157, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(157, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPECLEAR.bit.GPIO157 = 1;
// LED14
GPIO_SetupPinMux(158, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(158, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPECLEAR.bit.GPIO158 = 1;
// LED15
GPIO_SetupPinMux(159, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(159, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPECLEAR.bit.GPIO159 = 1;
// LED16
GPIO_SetupPinMux(160, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(160, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPFCLEAR.bit.GPIO160 = 1;
//WIZNET Reset
GPIO_SetupPinMux(0, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(0, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO0 = 1;
//ESP8266 Reset
GPIO_SetupPinMux(1, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(1, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO1 = 1;
//SPIRAM CS Chip Select
GPIO_SetupPinMux(19, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(19, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO19 = 1;
//DRV8874 #1 DIR Direction
GPIO_SetupPinMux(29, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(29, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO29 = 1;
//DRV8874 #2 DIR Direction
GPIO_SetupPinMux(32, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(32, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPBSET.bit.GPIO32 = 1;
//DAN28027 CS Chip Select
GPIO_SetupPinMux(9, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(9, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO9 = 1;
//MPU9250 CS Chip Select
GPIO_SetupPinMux(66, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(66, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPCSET.bit.GPIO66 = 1;
//WIZNET CS Chip Select
GPIO_SetupPinMux(125, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(125, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPDSET.bit.GPIO125 = 1;
//PushButton 1
GPIO_SetupPinMux(4, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(4, GPIO_INPUT, GPIO_PULLUP);
//PushButton 2
GPIO_SetupPinMux(5, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(5, GPIO_INPUT, GPIO_PULLUP);
//PushButton 3
GPIO_SetupPinMux(6, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(6, GPIO_INPUT, GPIO_PULLUP);
//PushButton 4
GPIO_SetupPinMux(7, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(7, GPIO_INPUT, GPIO_PULLUP);
//Joy Stick Pushbutton
GPIO_SetupPinMux(8, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(8, GPIO_INPUT, GPIO_PULLUP);
// ----- code for CAN start here -----
//GPIO17 - CANRXB
GPIO_SetupPinMux(17, GPIO_MUX_CPU1, 2);
GPIO_SetupPinOptions(17, GPIO_INPUT, GPIO_ASYNC);
//GPIO12 - CANTXB
GPIO_SetupPinMux(12, GPIO_MUX_CPU1, 2);
GPIO_SetupPinOptions(12, GPIO_OUTPUT, GPIO_PUSHPULL);
//GPIO14 - RCServo
GPIO_SetupPinMux(14, GPIO_MUX_CPU1,1);
// ----- code for CAN end here -----
// ----- code for CAN start here -----
// Initialize the CAN controller
InitCANB();
// Set up the CAN bus bit rate to 1000 kbps
setCANBitRate(200000000, 1000000);
// Enables Interrupt line 0, Error & Status Change interrupts in CAN_CTL register.
CanbRegs.CAN_CTL.bit.IE0= 1;
CanbRegs.CAN_CTL.bit.EIE= 1;
// ----- code for CAN end here -----
// Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2837xD_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this project
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.TIMER0_INT = &cpu_timer0_isr;
PieVectTable.TIMER1_INT = &cpu_timer1_isr;
PieVectTable.TIMER2_INT = &cpu_timer2_isr;
PieVectTable.SCIA_RX_INT = &RXAINT_recv_ready;
PieVectTable.SCIB_RX_INT = &RXBINT_recv_ready;
PieVectTable.SCIC_RX_INT = &RXCINT_recv_ready;
PieVectTable.SCID_RX_INT = &RXDINT_recv_ready;
PieVectTable.SCIA_TX_INT = &TXAINT_data_sent;
PieVectTable.SCIB_TX_INT = &TXBINT_data_sent;
PieVectTable.SCIC_TX_INT = &TXCINT_data_sent;
PieVectTable.SCID_TX_INT = &TXDINT_data_sent;
PieVectTable.SPIB_RX_INT = &SPIB_isr;
PieVectTable.EMIF_ERROR_INT = &SWI_isr;
// ----- code for CAN start here -----
PieVectTable.CANB0_INT = &can_isr;
// ----- code for CAN end here -----
EDIS; // This is needed to disable write to EALLOW protected registers
// Initialize the CpuTimers Device Peripheral. This function can be
// found in F2837xD_CpuTimers.c
InitCpuTimers();
// Configure CPU-Timer 0, 1, and 2 to interrupt every given period:
// 200MHz CPU Freq, Period (in uSeconds)
ConfigCpuTimer(&CpuTimer0, LAUNCHPAD_CPU_FREQUENCY, 1000);
ConfigCpuTimer(&CpuTimer1, LAUNCHPAD_CPU_FREQUENCY, 4000);
ConfigCpuTimer(&CpuTimer2, LAUNCHPAD_CPU_FREQUENCY, 40000);
// Enable CpuTimer Interrupt bit TIE
CpuTimer0Regs.TCR.all = 0x4000;
CpuTimer1Regs.TCR.all = 0x4000;
CpuTimer2Regs.TCR.all = 0x4000;
init_serialSCIA(&SerialA,115200);
setupSpib();
// JW ----- call function in the main loop -----
init_eQEPs();
// JW: ----- Pinmux setup -----
GPIO_SetupPinMux(2, GPIO_MUX_CPU1,1);
GPIO_SetupPinMux(3, GPIO_MUX_CPU1,1);
// JW: ----- PwM setting ------
// with TBCTL for Lab3 2
EPwm2Regs.TBCTL.bit.CLKDIV = 0;
EPwm2Regs.TBCTL.bit.CTRMODE = 0;
EPwm2Regs.TBCTL.bit.FREE_SOFT = 2;
EPwm2Regs.TBCTL.bit.PHSEN = 0;
//With TBCTR
EPwm2Regs.TBCTR = 0;
//WIth TBPRD
EPwm2Regs.TBPRD = 2500;
//WITH CMPA For A
//GC controlled from the controleffort function below
EPwm2Regs.CMPA.bit.CMPA = 0;
//WITH AQCTLA
EPwm2Regs.AQCTLA.bit.CAU = 1;
EPwm2Regs.AQCTLA.bit.ZRO = 2;
//WITH CMPB
//GC controlled from the controleffort function below
EPwm2Regs.CMPB.bit.CMPB = 0;
//WITH AQCTLB For B
EPwm2Regs.AQCTLB.bit.CBU = 1;
EPwm2Regs.AQCTLB.bit.ZRO = 2;
// servo control using epwm 8
EPwm8Regs.TBCTL.bit.CLKDIV = 4;
EPwm8Regs.TBCTL.bit.CTRMODE = 0;
EPwm8Regs.TBCTL.bit.FREE_SOFT = 2;
EPwm8Regs.TBCTL.bit.PHSEN = 0;
//With TBCTR
EPwm8Regs.TBCTR = 0;
//WIth TBPRD
EPwm8Regs.TBPRD = 62500;
//WITH CMPA For A
EPwm8Regs.CMPA.bit.CMPA = 0;
//WITH AQCTLA
EPwm8Regs.AQCTLA.bit.CAU = 1;
EPwm8Regs.AQCTLA.bit.ZRO = 2;
//WITH CMPB
EPwm8Regs.CMPB.bit.CMPB = 0;
//WITH AQCTLB For B
EPwm8Regs.AQCTLB.bit.CBU = 1;
EPwm8Regs.AQCTLB.bit.ZRO = 2;
// Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
// which is connected to CPU-Timer 1, and CPU int 14, which is connected
// to CPU-Timer 2: int 12 is for the SWI.
IER |= M_INT1;
IER |= M_INT6;
IER |= M_INT8; // SCIC SCID
IER |= M_INT9; // SCIA CANB
IER |= M_INT12;
IER |= M_INT13;
IER |= M_INT14;
// Enable TINT0 in the PIE: Group 1 interrupt 7
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
// Enable SWI in the PIE: Group 12 interrupt 9
PieCtrlRegs.PIEIER12.bit.INTx9 = 1;
PieCtrlRegs.PIEIER6.bit.INTx3 = 1; //SPiB
// ----- code for CAN start here -----
// Enable CANB in the PIE: Group 9 interrupt 7
PieCtrlRegs.PIEIER9.bit.INTx7 = 1;
// ----- code for CAN end here -----
// ----- code for CAN start here -----
// Enable the CAN interrupt signal
CanbRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN = 1;
// ----- code for CAN end here -----
init_serialSCIC(&SerialC,115200);
init_serialSCID(&SerialD,115200);
// Enable global Interrupts and higher priority real-time debug events
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
// ----- code for CAN start here -----
// // Transmit Message
// // Initialize the transmit message object used for sending CAN messages.
// // Message Object Parameters:
// // Message Object ID Number: 0
// // Message Identifier: 0x1
// // Message Frame: Standard
// // Message Type: Transmit
// // Message ID Mask: 0x0
// // Message Object Flags: Transmit Interrupt
// // Message Data Length: 4 Bytes
// //
// CANsetupMessageObject(CANB_BASE, TX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
// CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_TX_INT_ENABLE,
// TX_MSG_DATA_LENGTH);
// Measured Distance from 1
// Initialize the receive message object 1 used for receiving CAN messages.
// Message Object Parameters:
// Message Object ID Number: 1
// Message Identifier: 0x060b0101
// Message Frame: Standard
// Message Type: Receive
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 8 Bytes (Note that DLC field is a "don't care"
// for a Receive mailbox)
//
CANsetupMessageObject(CANB_BASE, RX_MSG_OBJ_ID_1, 0x060b0101, CAN_MSG_FRAME_EXT,
CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
RX_MSG_DATA_LENGTH);
// Measured Distance from 2
// Initialize the receive message object 2 used for receiving CAN messages.
// Message Object Parameters:
// Message Object ID Number: 2
// Message Identifier: 0x060b0102
// Message Frame: Standard
// Message Type: Receive
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 8 Bytes (Note that DLC field is a "don't care"
// for a Receive mailbox)
//
CANsetupMessageObject(CANB_BASE, RX_MSG_OBJ_ID_2, 0x060b0103, CAN_MSG_FRAME_EXT,
CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
RX_MSG_DATA_LENGTH);
// Measurement Quality from 1
// Initialize the receive message object 2 used for receiving CAN messages.
// Message Object Parameters:
// Message Object ID Number: 3
// Message Identifier: 0x060b0201
// Message Frame: Standard
// Message Type: Receive
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 8 Bytes (Note that DLC field is a "don't care"
// for a Receive mailbox)
//
CANsetupMessageObject(CANB_BASE, RX_MSG_OBJ_ID_3, 0x060b0201, CAN_MSG_FRAME_EXT,
CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
RX_MSG_DATA_LENGTH);
// Measurement Quality from 2
// Initialize the receive message object 2 used for receiving CAN messages.
// Message Object Parameters:
// Message Object ID Number: 4
// Message Identifier: 0x060b0202
// Message Frame: Standard
// Message Type: Receive
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 8 Bytes (Note that DLC field is a "don't care"
// for a Receive mailbox)
//
CANsetupMessageObject(CANB_BASE, RX_MSG_OBJ_ID_4, 0x060b0203, CAN_MSG_FRAME_EXT,
CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
RX_MSG_DATA_LENGTH);
//
// Start CAN module operations
//
CanbRegs.CAN_CTL.bit.Init = 0;
CanbRegs.CAN_CTL.bit.CCE = 0;
// // Initialize the transmit message object data buffer to be sent
// txMsgData[0] = 0x12;
// txMsgData[1] = 0x34;
// txMsgData[2] = 0x56;
// txMsgData[3] = 0x78;
// // Loop Forever - A message will be sent once per second.
// for(;;)
// {
//
// CANsendMessage(CANB_BASE, TX_MSG_OBJ_ID, TX_MSG_DATA_LENGTH, txMsgData);
// txMsgCount++;
// DEVICE_DELAY_US(1000000);
// }
// ----- code for CAN end here -----
// IDLE loop. Just sit and loop forever (optional):
while(1)
{
if (UARTPrint == 1 ) {
//serial_printf(&SerialA,"Num Timer2:%ld Num SerialRX: %ld\r\n",CpuTimer2.InterruptCount,numRXA);
//serial_printf(&SerialA,"a:%.3f,%.3f,%.3f g:%.3f,%.3f,%.3f\r\n",accelx,accely,accelz,gyrox,gyroy,gyroz);
serial_printf(&SerialA,"D1 %ld D2 %ld\n\r",distleft,distfront);
//serial_printf(&SerialA," St1 %ld St2 %ld\n\r",measure_status_1,measure_status_3);
//serial_printf(&SerialA," LWheel %.3f RWheel %.3f\n\r",LeftWheel,RightWheel);
//serial_printf(&SerialA," LWD %.3f m RWD %.3f m\n\r",LeftDistance,RightDistance);
//serial_printf(&SerialA," LV %.3f RV %.3f\n\r",VLeft,VRight);
//serial_printf(&SerialA," X: %.3f Y: %.3f\n\r",xR,yR);
UARTPrint = 0;
}
}
}
// SWI_isr, Using this interrupt as a Software started interrupt
__interrupt void SWI_isr(void) {
// These three lines of code allow SWI_isr, to be interrupted by other interrupt functions
// making it lower priority than all other Hardware interrupts.
PieCtrlRegs.PIEACK.all = PIEACK_GROUP12;
asm(" NOP"); // Wait one cycle
EINT; // Clear INTM to enable interrupts
// Insert SWI ISR Code here.......
numSWIcalls++;
DINT;
}
// cpu_timer0_isr - CPU Timer0 ISR
__interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
numTimer0calls++;
// if ((numTimer0calls%50) == 0) {
// PieCtrlRegs.PIEIFR12.bit.INTx9 = 1; // Manually cause the interrupt for the SWI
// }
if ((numTimer0calls%250) == 0) {
displayLEDletter(LEDdisplaynum);
LEDdisplaynum++;
if (LEDdisplaynum == 0xFFFF) { // prevent roll over exception
LEDdisplaynum = 0;
}
}
//Clear GPIO9 Low to act as a Slave Select. Right now, just to scope. Later to select DAN28027 chip
//GpioDataRegs.GPACLEAR.bit.GPIO9 = 1;
// SpibRegs.SPIFFRX.bit.RXFFIL = 2; // Issue the SPIB_RX_INT when two values are in the RX FIFO
// SpibRegs.SPITXBUF = 0x4A3B; // 0x4A3B and 0xB517 have no special meaning. Wanted to send
// SpibRegs.SPITXBUF = 0xB517; // something so you can see the pattern on the Oscilloscope
// SpibRegs.SPIFFRX.bit.RXFFIL = 3; // Issue the SPIB_RX_INT when two values are in the RX FIFO
// SpibRegs.SPITXBUF = 0xDA;
// SpibRegs.SPITXBUF = 500; // PWM value
// SpibRegs.SPITXBUF = 2200; // PWM Value
GpioDataRegs.GPCCLEAR.bit.GPIO66 = 1;
SpibRegs.SPIFFRX.bit.RXFFIL = 8;
SpibRegs.SPITXBUF = 0xBA00;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
if ((numTimer0calls%50) == 0) {
// Blink LaunchPad Red LED
GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;
}
// Acknowledge this interrupt to receive more interrupts from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
// cpu_timer1_isr - CPU Timer1 ISR
__interrupt void cpu_timer1_isr(void)
{
CpuTimer1.InterruptCount++;
numTimer1calls++;
LeftWheel = -readEncLeft();
RightWheel = readEncRight();
LeftDistance = LeftWheel*5.93/100.0;
RightDistance = RightWheel*5.93/100.0;
VLeft = (LeftDistance - LeftDistance1)/0.004;
VRight = (RightDistance - RightDistance1)/0.004;
// CG: -------- The function copy and paste from the Lab6 exercise 7------------
// if (measure_status_1 == 0) {
//
// distright = dis_1;
//
// } else {
//
// distright = 1400; // set to max reading if error
//
// }
//
// if (measure_status_3 == 0) {
//
// distfront = dis_3;
//
// } else {
//
// distfront = 1400; // set to max reading if error
//
// }
// JW: ----- wall following controller Right-----
//if right follow
// if (RWF = 1){
// turn = 0.12*Kpright * (ref_right-distright);
// Vref = 0.2;
//// else if( distright < 200 && distfront > 100){
//// RWF = 0;
//// turn = Kpfront * (ref_front-distfront);
//// }
// if (distfront <500){
// RWF = 0;
// turn = 5*Kpfront * (ref_front-distfront);
// }
// else{
// RWF = 1;
// }
//
// }
//if (distright < )
// JW: ----- wall following controller left for exercise 8-----
//if left follow
// if (measure_status_3 == 0) {
// distleft = dis_1;
// } else {
// distleft = 1400; // set to max reading if error
// }
// if (measure_status_1 == 0) {
// distfront = dis_3;
// } else {
// distfront = 1400; // set to max reading if error
// }
// if (LWF = 1){
// turn = -0.1 * Kpright * (350-distleft);
// Vref = 0.1;
// if (distfront <500){
// LWF = 0;
// turn = -1*Kpfront * (1400-distfront);
// }
// else{
// LWF = 1;
// }
// }
// CG: -------- The function for the PI control add from exercise 3 and 4------------
// CG: ----------- The turn error of the exercise 4 -----------
eturn = turn + (VLeft - VRight);
// CG: -------The eK error for left wheel for the exercise 3 ------
//eKLeft = Vref-VLeft;
// CG: -------The eK error for left wheel for the exercise 4 ------
eKLeft = Vref - VLeft - Kpturn *eturn;
//IKLeft = IKLeft1+0.004*(eKLeft +eKLeft1)/2;
if (fabs(uKLeft) > 10.0){
IKLeft = IKLeft1*0.95;
} else {
IKLeft = IKLeft1+0.004*(eKLeft +eKLeft1)/2;
}
uKLeft = Kp*eKLeft+Ki*IKLeft;
// CG: -------The eK error for left wheel for the exercise 3 ------
//eKRight = Vref-VRight;
// CG: -------The eK error for left wheel for the exercise 4 ------
eKRight = Vref - VRight + Kpturn *eturn;
//IKRight = IKRight1+0.004*(eKRight +eKRight1)/2;
if (fabs(uKRight) > 10.0){
IKRight = IKRight1*0.95;
} else {
IKRight = IKRight1+0.004*(eKRight +eKRight1)/2;
}
uKRight = Kp*eKRight+Ki*IKRight;
// xR = x_1+0.004*(x_dot +x_dot_1)/2;
setEPWM2A(uKRight);
setEPWM2B(-uKLeft);
//CG: -----Exercise 6 define parameter------
thetaL = LeftWheel;
thetaR = RightWheel;
phiR = Rwh/Wr*(thetaR-thetaL);
thetaAvg = 0.5*(thetaR+thetaL);
dotthetaL = thetaL-thetaL1;
dotthetaR = thetaR-thetaR1;
dotthetaAvg = 0.5*(dotthetaL+dotthetaR);
dotxR = Rwh * dotthetaAvg * cos(phiR);
dotyR = Rwh * dotthetaAvg * sin(phiR);
//CG: ----- Integral for Exercise 6-----
xR = xR_1 + dotxR;
yR = yR_1 + dotyR;
eKLeft1 = eKLeft;
IKLeft1 = IKLeft;
eKRight1 = eKRight;
IKRight1 = IKRight;
LeftDistance1 = LeftDistance;
RightDistance1 = RightDistance;
thetaL1 = thetaL;
thetaR1 = thetaR;
xR_1 = xR;
yR_1 = yR;
//servo ultrasound sensor data set
if (measure_status_1 == 0) {
dist_servo = dis_1;
} else {
dist_servo = 1400; // set to max reading if error
}
//scan servo
start_scan(start);
//CG : ------------------ The code for the exercise 2 Lab 6 -----
//setEPWM2A(URight);
//setEPWM2B(-ULeft);
// CG: ---------------The code copy and paste from the Lab6 exercise 5 ----------------------
if (NewLVData == 1) {
NewLVData = 0;
Vref = fromLVvalues[0];
turn = fromLVvalues[1];
// this variable starts the scan for the servo
start = fromLVvalues[2];
point = fromLVvalues[3];
printLV5 = fromLVvalues[4];
printLV6 = fromLVvalues[5];
printLV7 = fromLVvalues[6];
printLV8 = fromLVvalues[7];
}
if((numTimer1calls%68) == 0) { // change to the counter variable of you selected 4ms. timer
DataToLabView.floatData[0] = xR;
DataToLabView.floatData[1] = yR;
DataToLabView.floatData[2] = phiR;
// this sends the distance data from the servo sensor to labview
DataToLabView.floatData[3] = dist_servo;
DataToLabView.floatData[4] = xR_servo;
DataToLabView.floatData[5] = yR_servo;
DataToLabView.floatData[6] = (float)numTimer0calls*4.0;
DataToLabView.floatData[7] = (float)numTimer0calls*5.0;
LVsenddata[0] = '*'; // header for LVdata
LVsenddata[1] = '$';
for (int i=0;i<LVNUM_TOFROM_FLOATS*4;i++) {
if (i%2==0) {
LVsenddata[i+2] = DataToLabView.rawData[i/2] & 0xFF;
} else {
LVsenddata[i+2] = (DataToLabView.rawData[i/2]>>8) & 0xFF;
}
}
serial_sendSCID(&SerialD, LVsenddata, 4*LVNUM_TOFROM_FLOATS + 2);
}
}
// cpu_timer2_isr CPU Timer2 ISR
__interrupt void cpu_timer2_isr(void)
{
// Blink LaunchPad Blue LED
GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
CpuTimer2.InterruptCount++;
if ((CpuTimer2.InterruptCount % 10) == 0) {
UARTPrint = 1;
}
}
void setupSpib(void) //Call this function in main() somewhere after the DINT; line of code.
{
int16_t temp = 0;
//Step 1.
// cut and paste here all the SpibRegs initializations you found for part 3. Make sure the TXdelay in between each transfer to 0. Also dont forget to cut and paste the GPIO settings for GPIO9, 63, 64, 65, 66 which are also a part of the SPIB setup.
GPIO_SetupPinMux(9, GPIO_MUX_CPU1, 0); // Set as GPIO9 and used as DAN28027 SS
GPIO_SetupPinOptions(9, GPIO_OUTPUT, GPIO_PUSHPULL); // Make GPIO9 an Output Pin
GpioDataRegs.GPASET.bit.GPIO9 = 1; //Initially Set GPIO9/SS High so DAN28027 is not selected
GPIO_SetupPinMux(66, GPIO_MUX_CPU1, 0); // Set as GPIO66 and used as MPU-9250 SS
GPIO_SetupPinOptions(66, GPIO_OUTPUT, GPIO_PUSHPULL); // Make GPIO66 an Output Pin
GpioDataRegs.GPCSET.bit.GPIO66 = 1; //Initially Set GPIO66/SS High so MPU-9250 is not selected
GPIO_SetupPinMux(63, GPIO_MUX_CPU1, 15); //Set GPIO63 pin to SPISIMOB
GPIO_SetupPinMux(64, GPIO_MUX_CPU1, 15); //Set GPIO64 pin to SPISOMIB
GPIO_SetupPinMux(65, GPIO_MUX_CPU1, 15); //Set GPIO65 pin to SPICLKB
EALLOW;
...
This file has been truncated, please download it to see its full contents.
//#############################################################################
// FILE: LAB6starter_main.c
//
// TITLE: Lab Starter
//#############################################################################
// Included Files
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <limits.h>
#include "F28x_Project.h"
#include "driverlib.h"
#include "device.h"
#include "F28379dSerial.h"
#include "LEDPatterns.h"
#include "song.h"
#include "dsp.h"
#include "fpu32/fpu_rfft.h"
#define PI 3.1415926535897932384626433832795
#define TWOPI 6.283185307179586476925286766559
#define HALFPI 1.5707963267948966192313216916398
// The Launchpad's CPU Frequency set to 200 you should not change this value
#define LAUNCHPAD_CPU_FREQUENCY 200
// ----- code for CAN start here -----
#include "F28379dCAN.h"
//#define TX_MSG_DATA_LENGTH 4
//#define TX_MSG_OBJ_ID 0 //transmit
#define RX_MSG_DATA_LENGTH 8
#define RX_MSG_OBJ_ID_1 1 //measurement from sensor 1
#define RX_MSG_OBJ_ID_2 2 //measurement from sensor 2
#define RX_MSG_OBJ_ID_3 3 //quality from sensor 1
#define RX_MSG_OBJ_ID_4 4 //quality from sensor 2
// ----- code for CAN end here -----
// Interrupt Service Routines predefinition
__interrupt void cpu_timer0_isr(void);
__interrupt void cpu_timer1_isr(void);
__interrupt void cpu_timer2_isr(void);
__interrupt void SWI_isr(void);
// ----- code for CAN start here -----
__interrupt void can_isr(void);
// ----- code for CAN end here -----
__interrupt void SPIB_isr(void);
void setupSpib(void);
// JW: ----- code for motor reading ------
void init_eQEPs(void);
// JW: ----- float for left motor recording ------
float readEncLeft(void);
// JW: ----- float for right motor recording ------
float readEncRight(void);
// JW: ----- float for the radius of left motor ------
float LeftWheel = 0;
// JW: ----- float for the radius of Right motor ------
float RightWheel = 0;
// JW: ----- float for the left wheel travel distance ----
float LeftDistance = 0;
float LeftDistance1 = 0;
// JW: ----- float for the Right wheel travel distance ----
float RightDistance = 0;
float RightDistance1 = 0;
// JW: ------call the EPWM2A and 2B -----
void setEPWM2A(float controleffort);
void setEPWM2B(float controleffort);
// predefinition for the servo control functions
void start_scan(int start);
void setEPWM8A_RCServo(float angle);
// JW: ------call the ULeft and URight -----
float ULeft = 5.0;
float URight = 5.0;
// ------call the VLeft and VRight -----
float VRight = 0;
float VLeft = 0;
// JW: -----Setup value for PI controller Exercise 3------
float eKLeft = 0;
float eKLeft1 = 0;
float IKLeft = 0;
float IKLeft1 = 0;
float uKLeft = 0;
float eKRight = 0;
float eKRight1 = 0;
float IKRight = 0;
float IKRight1 = 0;
float uKRight = 0;
float KpKidiv = 1;
//Servo scan variable
int16_t start = 0;
float servo_angle = 0;
float dist_servo = 0;
int16_t updown = 1;
float xR_servo = 0;
float yR_servo = 0;
float Kp = 3.0;
float Ki = 25.0;
float Vref = 0;
//JW: -----Setup turn error for PI controller Exercise 4------
float eturn = 0;
float turn = 0;
float Kpturn = 3;
//JW: -----The code copy and paste from Lab6 exercise 5------
float printLV3 = 0;
float printLV4 = 0;
float printLV5 = 0;
float printLV6 = 0;
float printLV7 = 0;
float printLV8 = 0;
float x = 0;
float y = 0;
float bearing = 0;
extern uint16_t NewLVData;
extern float fromLVvalues[LVNUM_TOFROM_FLOATS];
extern LVSendFloats_t DataToLabView;
extern char LVsenddata[LVNUM_TOFROM_FLOATS*4+2];
extern uint16_t newLinuxCommands;
extern float LinuxCommands[CMDNUM_FROM_FLOATS];
uint32_t numTimer1calls = 0;
//JW: -----Defined the variable for Lab6 exercise 6------
// Robot Width
float Wr = 0.173;
// Radius Wheel
float Rwh = 0.06;
//Wheel Rotation Angle
float thetaL = 0;
float thetaL1 = 0;
float dotthetaL = 0;
float thetaR = 0;
float thetaR1 = 0;
float dotthetaR = 0;
float thetaAvg = 0;
float dotthetaAvg = 0;
//Robot Pose X Y coordinate
float xR = 0;
float xR_1 = 0;
float dotxR = 0;
float yR =0;
float yR_1 =0;
float dotyR =0;
// Robot Pose Angle or Bearing
float phiR = 0;
//JW: -----Defined the variable for Lab6 exercise 7------
float Kpright = 0.001;
float Kpfront = 0.0002;
float ref_right = 300.0;
float ref_front = 1400.0;
float ref_left = 1400.0;
float distright = 0.0;
float distfront = 0.0;
float distleft = 0.0;
uint16_t RWF = 1;
uint16_t LWF = 1;
float left_ref_dist = 450;
float turn_sat = 0.05;
// Count variables
uint32_t numTimer0calls = 0;
uint32_t numSWIcalls = 0;
extern uint32_t numRXA;
uint16_t UARTPrint = 0;
uint16_t LEDdisplaynum = 0;
int16_t accelx_raw = 0;
int16_t accely_raw = 0;
int16_t accelz_raw = 0;
int16_t gyrox_raw = 0;
int16_t gyroy_raw = 0;
int16_t gyroz_raw = 0;
float accelx = 0;
float accely = 0;
float accelz = 0;
float gyrox = 0;
float gyroy = 0;
float gyroz = 0;
int32_t SpibNumCalls = 0;
// ----- code for CAN start here -----
// volatile uint32_t txMsgCount = 0;
// extern uint16_t txMsgData[4];
volatile uint32_t rxMsgCount_1 = 0;
volatile uint32_t rxMsgCount_3 = 0;
extern uint16_t rxMsgData[8];
uint32_t dis_raw_1[2];
uint32_t dis_raw_3[2];
uint32_t dis_1 = 0;
uint32_t dis_3 = 0;
uint32_t quality_raw_1[4];
uint32_t quality_raw_3[4];
float quality_1 = 0.0;
float quality_3 = 0.0;
uint32_t lightlevel_raw_1[4];
uint32_t lightlevel_raw_3[4];
float lightlevel_1 = 0.0;
float lightlevel_3 = 0.0;
uint32_t measure_status_1 = 0;
uint32_t measure_status_3 = 0;
volatile uint32_t errorFlag = 0;
// ----- code for CAN end here -----
void main(void)
{
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
InitSysCtrl();
InitGpio();
// Blue LED on LaunchPad
GPIO_SetupPinMux(31, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(31, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO31 = 1;
// Red LED on LaunchPad
GPIO_SetupPinMux(34, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(34, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPBSET.bit.GPIO34 = 1;
// LED1 and PWM Pin
GPIO_SetupPinMux(22, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(22, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPACLEAR.bit.GPIO22 = 1;
// LED2
GPIO_SetupPinMux(94, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(94, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPCCLEAR.bit.GPIO94 = 1;
// LED3
GPIO_SetupPinMux(95, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(95, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPCCLEAR.bit.GPIO95 = 1;
// LED4
GPIO_SetupPinMux(97, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(97, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPDCLEAR.bit.GPIO97 = 1;
// LED5
GPIO_SetupPinMux(111, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(111, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPDCLEAR.bit.GPIO111 = 1;
// LED6
GPIO_SetupPinMux(130, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(130, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPECLEAR.bit.GPIO130 = 1;
// LED7
GPIO_SetupPinMux(131, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(131, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPECLEAR.bit.GPIO131 = 1;
// LED8
GPIO_SetupPinMux(25, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(25, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPACLEAR.bit.GPIO25 = 1;
// LED9
GPIO_SetupPinMux(26, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(26, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPACLEAR.bit.GPIO26 = 1;
// LED10
GPIO_SetupPinMux(27, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(27, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPACLEAR.bit.GPIO27 = 1;
// LED11
GPIO_SetupPinMux(60, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(60, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPBCLEAR.bit.GPIO60 = 1;
// LED12
GPIO_SetupPinMux(61, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(61, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1;
// LED13
GPIO_SetupPinMux(157, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(157, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPECLEAR.bit.GPIO157 = 1;
// LED14
GPIO_SetupPinMux(158, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(158, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPECLEAR.bit.GPIO158 = 1;
// LED15
GPIO_SetupPinMux(159, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(159, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPECLEAR.bit.GPIO159 = 1;
// LED16
GPIO_SetupPinMux(160, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(160, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPFCLEAR.bit.GPIO160 = 1;
//WIZNET Reset
GPIO_SetupPinMux(0, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(0, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO0 = 1;
//ESP8266 Reset
GPIO_SetupPinMux(1, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(1, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO1 = 1;
//SPIRAM CS Chip Select
GPIO_SetupPinMux(19, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(19, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO19 = 1;
//DRV8874 #1 DIR Direction
GPIO_SetupPinMux(29, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(29, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO29 = 1;
//DRV8874 #2 DIR Direction
GPIO_SetupPinMux(32, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(32, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPBSET.bit.GPIO32 = 1;
//DAN28027 CS Chip Select
GPIO_SetupPinMux(9, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(9, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPASET.bit.GPIO9 = 1;
//MPU9250 CS Chip Select
GPIO_SetupPinMux(66, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(66, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPCSET.bit.GPIO66 = 1;
//WIZNET CS Chip Select
GPIO_SetupPinMux(125, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(125, GPIO_OUTPUT, GPIO_PUSHPULL);
GpioDataRegs.GPDSET.bit.GPIO125 = 1;
//PushButton 1
GPIO_SetupPinMux(4, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(4, GPIO_INPUT, GPIO_PULLUP);
//PushButton 2
GPIO_SetupPinMux(5, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(5, GPIO_INPUT, GPIO_PULLUP);
//PushButton 3
GPIO_SetupPinMux(6, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(6, GPIO_INPUT, GPIO_PULLUP);
//PushButton 4
GPIO_SetupPinMux(7, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(7, GPIO_INPUT, GPIO_PULLUP);
//Joy Stick Pushbutton
GPIO_SetupPinMux(8, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(8, GPIO_INPUT, GPIO_PULLUP);
// ----- code for CAN start here -----
//GPIO17 - CANRXB
GPIO_SetupPinMux(17, GPIO_MUX_CPU1, 2);
GPIO_SetupPinOptions(17, GPIO_INPUT, GPIO_ASYNC);
//GPIO12 - CANTXB
GPIO_SetupPinMux(12, GPIO_MUX_CPU1, 2);
GPIO_SetupPinOptions(12, GPIO_OUTPUT, GPIO_PUSHPULL);
//GPIO14 - RCServo
GPIO_SetupPinMux(14, GPIO_MUX_CPU1,1);
// ----- code for CAN end here -----
// ----- code for CAN start here -----
// Initialize the CAN controller
InitCANB();
// Set up the CAN bus bit rate to 1000 kbps
setCANBitRate(200000000, 1000000);
// Enables Interrupt line 0, Error & Status Change interrupts in CAN_CTL register.
CanbRegs.CAN_CTL.bit.IE0= 1;
CanbRegs.CAN_CTL.bit.EIE= 1;
// ----- code for CAN end here -----
// Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2837xD_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this project
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.TIMER0_INT = &cpu_timer0_isr;
PieVectTable.TIMER1_INT = &cpu_timer1_isr;
PieVectTable.TIMER2_INT = &cpu_timer2_isr;
PieVectTable.SCIA_RX_INT = &RXAINT_recv_ready;
PieVectTable.SCIB_RX_INT = &RXBINT_recv_ready;
PieVectTable.SCIC_RX_INT = &RXCINT_recv_ready;
PieVectTable.SCID_RX_INT = &RXDINT_recv_ready;
PieVectTable.SCIA_TX_INT = &TXAINT_data_sent;
PieVectTable.SCIB_TX_INT = &TXBINT_data_sent;
PieVectTable.SCIC_TX_INT = &TXCINT_data_sent;
PieVectTable.SCID_TX_INT = &TXDINT_data_sent;
PieVectTable.SPIB_RX_INT = &SPIB_isr;
PieVectTable.EMIF_ERROR_INT = &SWI_isr;
// ----- code for CAN start here -----
PieVectTable.CANB0_INT = &can_isr;
// ----- code for CAN end here -----
EDIS; // This is needed to disable write to EALLOW protected registers
// Initialize the CpuTimers Device Peripheral. This function can be
// found in F2837xD_CpuTimers.c
InitCpuTimers();
// Configure CPU-Timer 0, 1, and 2 to interrupt every given period:
// 200MHz CPU Freq, Period (in uSeconds)
ConfigCpuTimer(&CpuTimer0, LAUNCHPAD_CPU_FREQUENCY, 1000);
ConfigCpuTimer(&CpuTimer1, LAUNCHPAD_CPU_FREQUENCY, 4000);
ConfigCpuTimer(&CpuTimer2, LAUNCHPAD_CPU_FREQUENCY, 40000);
// Enable CpuTimer Interrupt bit TIE
CpuTimer0Regs.TCR.all = 0x4000;
CpuTimer1Regs.TCR.all = 0x4000;
CpuTimer2Regs.TCR.all = 0x4000;
init_serialSCIA(&SerialA,115200);
setupSpib();
// JW ----- call function in the main loop -----
init_eQEPs();
// JW: ----- Pinmux setup -----
GPIO_SetupPinMux(2, GPIO_MUX_CPU1,1);
GPIO_SetupPinMux(3, GPIO_MUX_CPU1,1);
// JW: ----- PwM setting ------
// with TBCTL for Lab3 2
EPwm2Regs.TBCTL.bit.CLKDIV = 0;
EPwm2Regs.TBCTL.bit.CTRMODE = 0;
EPwm2Regs.TBCTL.bit.FREE_SOFT = 2;
EPwm2Regs.TBCTL.bit.PHSEN = 0;
//With TBCTR
EPwm2Regs.TBCTR = 0;
//WIth TBPRD
EPwm2Regs.TBPRD = 2500;
//WITH CMPA For A
//GC controlled from the controleffort function below
EPwm2Regs.CMPA.bit.CMPA = 0;
//WITH AQCTLA
EPwm2Regs.AQCTLA.bit.CAU = 1;
EPwm2Regs.AQCTLA.bit.ZRO = 2;
//WITH CMPB
//GC controlled from the controleffort function below
EPwm2Regs.CMPB.bit.CMPB = 0;
//WITH AQCTLB For B
EPwm2Regs.AQCTLB.bit.CBU = 1;
EPwm2Regs.AQCTLB.bit.ZRO = 2;
// servo control using epwm 8
EPwm8Regs.TBCTL.bit.CLKDIV = 4;
EPwm8Regs.TBCTL.bit.CTRMODE = 0;
EPwm8Regs.TBCTL.bit.FREE_SOFT = 2;
EPwm8Regs.TBCTL.bit.PHSEN = 0;
//With TBCTR
EPwm8Regs.TBCTR = 0;
//WIth TBPRD
EPwm8Regs.TBPRD = 62500;
//WITH CMPA For A
EPwm8Regs.CMPA.bit.CMPA = 0;
//WITH AQCTLA
EPwm8Regs.AQCTLA.bit.CAU = 1;
EPwm8Regs.AQCTLA.bit.ZRO = 2;
//WITH CMPB
EPwm8Regs.CMPB.bit.CMPB = 0;
//WITH AQCTLB For B
EPwm8Regs.AQCTLB.bit.CBU = 1;
EPwm8Regs.AQCTLB.bit.ZRO = 2;
// Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
// which is connected to CPU-Timer 1, and CPU int 14, which is connected
// to CPU-Timer 2: int 12 is for the SWI.
IER |= M_INT1;
IER |= M_INT6;
IER |= M_INT8; // SCIC SCID
IER |= M_INT9; // SCIA CANB
IER |= M_INT12;
IER |= M_INT13;
IER |= M_INT14;
// Enable TINT0 in the PIE: Group 1 interrupt 7
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
// Enable SWI in the PIE: Group 12 interrupt 9
PieCtrlRegs.PIEIER12.bit.INTx9 = 1;
PieCtrlRegs.PIEIER6.bit.INTx3 = 1; //SPiB
// ----- code for CAN start here -----
// Enable CANB in the PIE: Group 9 interrupt 7
PieCtrlRegs.PIEIER9.bit.INTx7 = 1;
// ----- code for CAN end here -----
// ----- code for CAN start here -----
// Enable the CAN interrupt signal
CanbRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN = 1;
// ----- code for CAN end here -----
init_serialSCIC(&SerialC,115200);
init_serialSCID(&SerialD,115200);
// Enable global Interrupts and higher priority real-time debug events
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
// ----- code for CAN start here -----
// // Transmit Message
// // Initialize the transmit message object used for sending CAN messages.
// // Message Object Parameters:
// // Message Object ID Number: 0
// // Message Identifier: 0x1
// // Message Frame: Standard
// // Message Type: Transmit
// // Message ID Mask: 0x0
// // Message Object Flags: Transmit Interrupt
// // Message Data Length: 4 Bytes
// //
// CANsetupMessageObject(CANB_BASE, TX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
// CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_TX_INT_ENABLE,
// TX_MSG_DATA_LENGTH);
// Measured Distance from 1
// Initialize the receive message object 1 used for receiving CAN messages.
// Message Object Parameters:
// Message Object ID Number: 1
// Message Identifier: 0x060b0101
// Message Frame: Standard
// Message Type: Receive
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 8 Bytes (Note that DLC field is a "don't care"
// for a Receive mailbox)
//
CANsetupMessageObject(CANB_BASE, RX_MSG_OBJ_ID_1, 0x060b0101, CAN_MSG_FRAME_EXT,
CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
RX_MSG_DATA_LENGTH);
// Measured Distance from 2
// Initialize the receive message object 2 used for receiving CAN messages.
// Message Object Parameters:
// Message Object ID Number: 2
// Message Identifier: 0x060b0102
// Message Frame: Standard
// Message Type: Receive
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 8 Bytes (Note that DLC field is a "don't care"
// for a Receive mailbox)
//
CANsetupMessageObject(CANB_BASE, RX_MSG_OBJ_ID_2, 0x060b0103, CAN_MSG_FRAME_EXT,
CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
RX_MSG_DATA_LENGTH);
// Measurement Quality from 1
// Initialize the receive message object 2 used for receiving CAN messages.
// Message Object Parameters:
// Message Object ID Number: 3
// Message Identifier: 0x060b0201
// Message Frame: Standard
// Message Type: Receive
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 8 Bytes (Note that DLC field is a "don't care"
// for a Receive mailbox)
//
CANsetupMessageObject(CANB_BASE, RX_MSG_OBJ_ID_3, 0x060b0201, CAN_MSG_FRAME_EXT,
CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
RX_MSG_DATA_LENGTH);
// Measurement Quality from 2
// Initialize the receive message object 2 used for receiving CAN messages.
// Message Object Parameters:
// Message Object ID Number: 4
// Message Identifier: 0x060b0202
// Message Frame: Standard
// Message Type: Receive
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 8 Bytes (Note that DLC field is a "don't care"
// for a Receive mailbox)
//
CANsetupMessageObject(CANB_BASE, RX_MSG_OBJ_ID_4, 0x060b0203, CAN_MSG_FRAME_EXT,
CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
RX_MSG_DATA_LENGTH);
//
// Start CAN module operations
//
CanbRegs.CAN_CTL.bit.Init = 0;
CanbRegs.CAN_CTL.bit.CCE = 0;
// // Initialize the transmit message object data buffer to be sent
// txMsgData[0] = 0x12;
// txMsgData[1] = 0x34;
// txMsgData[2] = 0x56;
// txMsgData[3] = 0x78;
// // Loop Forever - A message will be sent once per second.
// for(;;)
// {
//
// CANsendMessage(CANB_BASE, TX_MSG_OBJ_ID, TX_MSG_DATA_LENGTH, txMsgData);
// txMsgCount++;
// DEVICE_DELAY_US(1000000);
// }
// ----- code for CAN end here -----
// IDLE loop. Just sit and loop forever (optional):
while(1)
{
if (UARTPrint == 1 ) {
//serial_printf(&SerialA,"Num Timer2:%ld Num SerialRX: %ld\r\n",CpuTimer2.InterruptCount,numRXA);
//serial_printf(&SerialA,"a:%.3f,%.3f,%.3f g:%.3f,%.3f,%.3f\r\n",accelx,accely,accelz,gyrox,gyroy,gyroz);
serial_printf(&SerialA,"D1 %ld D2 %ld\n\r",distleft,distfront);
//serial_printf(&SerialA," St1 %ld St2 %ld\n\r",measure_status_1,measure_status_3);
//serial_printf(&SerialA," LWheel %.3f RWheel %.3f\n\r",LeftWheel,RightWheel);
//serial_printf(&SerialA," LWD %.3f m RWD %.3f m\n\r",LeftDistance,RightDistance);
//serial_printf(&SerialA," LV %.3f RV %.3f\n\r",VLeft,VRight);
//serial_printf(&SerialA," X: %.3f Y: %.3f\n\r",xR,yR);
UARTPrint = 0;
}
}
}
// SWI_isr, Using this interrupt as a Software started interrupt
__interrupt void SWI_isr(void) {
// These three lines of code allow SWI_isr, to be interrupted by other interrupt functions
// making it lower priority than all other Hardware interrupts.
PieCtrlRegs.PIEACK.all = PIEACK_GROUP12;
asm(" NOP"); // Wait one cycle
EINT; // Clear INTM to enable interrupts
// Insert SWI ISR Code here.......
numSWIcalls++;
DINT;
}
// cpu_timer0_isr - CPU Timer0 ISR
__interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
numTimer0calls++;
// if ((numTimer0calls%50) == 0) {
// PieCtrlRegs.PIEIFR12.bit.INTx9 = 1; // Manually cause the interrupt for the SWI
// }
if ((numTimer0calls%250) == 0) {
displayLEDletter(LEDdisplaynum);
LEDdisplaynum++;
if (LEDdisplaynum == 0xFFFF) { // prevent roll over exception
LEDdisplaynum = 0;
}
}
//Clear GPIO9 Low to act as a Slave Select. Right now, just to scope. Later to select DAN28027 chip
//GpioDataRegs.GPACLEAR.bit.GPIO9 = 1;
// SpibRegs.SPIFFRX.bit.RXFFIL = 2; // Issue the SPIB_RX_INT when two values are in the RX FIFO
// SpibRegs.SPITXBUF = 0x4A3B; // 0x4A3B and 0xB517 have no special meaning. Wanted to send
// SpibRegs.SPITXBUF = 0xB517; // something so you can see the pattern on the Oscilloscope
// SpibRegs.SPIFFRX.bit.RXFFIL = 3; // Issue the SPIB_RX_INT when two values are in the RX FIFO
// SpibRegs.SPITXBUF = 0xDA;
// SpibRegs.SPITXBUF = 500; // PWM value
// SpibRegs.SPITXBUF = 2200; // PWM Value
GpioDataRegs.GPCCLEAR.bit.GPIO66 = 1;
SpibRegs.SPIFFRX.bit.RXFFIL = 8;
SpibRegs.SPITXBUF = 0xBA00;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
SpibRegs.SPITXBUF = 0x0000;
if ((numTimer0calls%50) == 0) {
// Blink LaunchPad Red LED
GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;
}
// Acknowledge this interrupt to receive more interrupts from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
// cpu_timer1_isr - CPU Timer1 ISR
__interrupt void cpu_timer1_isr(void)
{
CpuTimer1.InterruptCount++;
numTimer1calls++;
LeftWheel = -readEncLeft();
RightWheel = readEncRight();
LeftDistance = LeftWheel*5.93/100.0;
RightDistance = RightWheel*5.93/100.0;
VLeft = (LeftDistance - LeftDistance1)/0.004;
VRight = (RightDistance - RightDistance1)/0.004;
// CG: -------- The function copy and paste from the Lab6 exercise 7------------
// if (measure_status_1 == 0) {
//
// distright = dis_1;
//
// } else {
//
// distright = 1400; // set to max reading if error
//
// }
//
// if (measure_status_3 == 0) {
//
// distfront = dis_3;
//
// } else {
//
// distfront = 1400; // set to max reading if error
//
// }
// JW: ----- wall following controller Right-----
//if right follow
// if (RWF = 1){
// turn = 0.12*Kpright * (ref_right-distright);
// Vref = 0.2;
//// else if( distright < 200 && distfront > 100){
//// RWF = 0;
//// turn = Kpfront * (ref_front-distfront);
//// }
// if (distfront <500){
// RWF = 0;
// turn = 5*Kpfront * (ref_front-distfront);
// }
// else{
// RWF = 1;
// }
//
// }
//if (distright < )
// JW: ----- wall following controller left for exercise 8-----
//if left follow
if (measure_status_1 == 0) {
distleft = dis_1;
} else {
distleft = 1400; // set to max reading if error
}
if (measure_status_3 == 0) {
distfront = dis_3;
} else {
distfront = 1400; // set to max reading if error
}
if (LWF == 1){
Vref = 0.1;
if (fabs(turn) > turn_sat){
turn = turn*0.95;
} else {
turn = -1 * Kpright * (left_ref_dist-distleft);
}
}
if (distfront <500){
LWF = 0;
if (fabs(turn) > turn_sat){
turn = turn*0.95;
} else {
turn = -1*Kpfront * (1400-distfront);
}
}
else{
LWF = 1;
}
// CG: -------- The function for the PI control add from exercise 3 and 4------------
// CG: ----------- The turn error of the exercise 4 -----------
eturn = turn + (VLeft - VRight);
// CG: -------The eK error for left wheel for the exercise 3 ------
//eKLeft = Vref-VLeft;
// CG: -------The eK error for left wheel for the exercise 4 ------
eKLeft = Vref - VLeft - Kpturn *eturn;
//IKLeft = IKLeft1+0.004*(eKLeft +eKLeft1)/2;
if (fabs(uKLeft) > 5.0){
IKLeft = IKLeft1*0.95;
} else {
IKLeft = IKLeft1+0.004*(eKLeft +eKLeft1)/2;
}
uKLeft = (Kp*eKLeft+Ki*IKLeft)/KpKidiv;
// CG: -------The eK error for left wheel for the exercise 3 ------
//eKRight = Vref-VRight;
// CG: -------The eK error for left wheel for the exercise 4 ------
eKRight = Vref - VRight + Kpturn *eturn;
//IKRight = IKRight1+0.004*(eKRight +eKRight1)/2;
if (fabs(uKRight) > 5.0){
IKRight = IKRight1*0.95;
} else {
IKRight = IKRight1+0.004*(eKRight +eKRight1)/2;
}
uKRight = (Kp*eKRight+Ki*IKRight)/KpKidiv;
// xR = x_1+0.004*(x_dot +x_dot_1)/2;
setEPWM2A(uKRight);
setEPWM2B(-uKLeft);
//CG: -----Exercise 6 define parameter------
thetaL = LeftWheel;
thetaR = RightWheel;
phiR = Rwh/Wr*(thetaR-thetaL);
thetaAvg = 0.5*(thetaR+thetaL);
dotthetaL = thetaL-thetaL1;
dotthetaR = thetaR-thetaR1;
dotthetaAvg = 0.5*(dotthetaL+dotthetaR);
dotxR = Rwh * dotthetaAvg * cos(phiR);
dotyR = Rwh * dotthetaAvg * sin(phiR);
//CG: ----- Integral for Exercise 6-----
xR = xR_1 + dotxR;
yR = yR_1 + dotyR;
eKLeft1 = eKLeft;
IKLeft1 = IKLeft;
eKRight1 = eKRight;
IKRight1 = IKRight;
LeftDistance1 = LeftDistance;
RightDistance1 = RightDistance;
thetaL1 = thetaL;
thetaR1 = thetaR;
xR_1 = xR;
yR_1 = yR;
//servo ultrasound sensor data set
if (measure_status_1 == 0) {
dist_servo = dis_1;
} else {
dist_servo = 1400; // set to max reading if error
}
//scan servo
start_scan(start);
if (dist_servo <1000){
xR_servo = xR*1000 + dist_servo * sin((-45*PI/180 - phiR));
yR_servo = yR*1000 + dist_servo * cos((-45*PI/180 - phiR));
// xR_servo = xR*1000 + dist_servo * sin((servo_angle*PI/180 - phiR));
// yR_servo = yR*1000 + dist_servo * cos((servo_angle*PI/180 - phiR));
}
else{
xR_servo = 10e6;
yR_servo = 10e6;
}
//CG : ------------------ The code for the exercise 2 Lab 6 -----
//setEPWM2A(URight);
//setEPWM2B(-ULeft);
// CG: ---------------The code copy and paste from the Lab6 exercise 5 ----------------------
if (NewLVData == 1) {
NewLVData = 0;
Vref = fromLVvalues[0];
turn = fromLVvalues[1];
// this variable starts the scan for the servo
start = fromLVvalues[2];
left_ref_dist = fromLVvalues[3];
turn_sat = fromLVvalues[4];
Kpright = fromLVvalues[5];
KpKidiv = fromLVvalues[6];
printLV8 = fromLVvalues[7];
}
if((numTimer1calls%68) == 0) { // change to the counter variable of you selected 4ms. timer
DataToLabView.floatData[0] = xR;
DataToLabView.floatData[1] = yR;
DataToLabView.floatData[2] = phiR;
// this sends the distance data from the servo sensor to labview
DataToLabView.floatData[3] = dist_servo;
DataToLabView.floatData[4] = xR_servo;
DataToLabView.floatData[5] = yR_servo;
DataToLabView.floatData[6] = (float)numTimer0calls*4.0;
DataToLabView.floatData[7] = (float)numTimer0calls*5.0;
LVsenddata[0] = '*'; // header for LVdata
LVsenddata[1] = '$';
for (int i=0;i<LVNUM_TOFROM_FLOATS*4;i++) {
if (i%2==0) {
LVsenddata[i+2] = DataToLabView.rawData[i/2] & 0xFF;
} else {
LVsenddata[i+2] = (DataToLabView.rawData[i/2]>>8) & 0xFF;
}
}
serial_sendSCID(&SerialD, LVsenddata, 4*LVNUM_TOFROM_FLOATS + 2);
}
}
// cpu_timer2_isr CPU Timer2 ISR
__interrupt void cpu_timer2_isr(void)
{
// Blink LaunchPad Blue LED
GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
CpuTimer2.InterruptCount++;
if ((CpuTimer2.InterruptCount % 10) == 0) {
UARTPrint = 1;
}
}
...
This file has been truncated, please download it to see its full contents.
Comments