|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
|||||
|
|||||
|
Out of the Box Camera Code
Ok, for the last few days I have been working on some "Out of the Box" camera code, designed for rookie teams, or teams that might otherwise not be able to have an autonomous program. It is really just a skeleton, to make the robot drive, but it has places for a team to add code to control their arm, or it would be easy to modify. The problem is that I dont have a robot to test it on (ours isnt done) and even if I did I dont have a place to test it.
Can anyone who has a few minutes read this code over and give suggestions, and note problems? It is only a modification of the default user_routines_fast.c and it is designed so you could replace your current user_routines_fast.c with it regardless of whether your team is running the v2.4 user_routines.c or you are using something else in its place. Oh yeah, the only places I modified are the very beginning where I defined a few things, the autonomous code section, and a few lines in the local IO data processing. Oh yeah, it compiled OK with the v2.4 code. After any bugs have been fixed I will upload the user_routines_fast.c file with a little readme file to help teams use it. Until then use it at your own risk .Disclaimer: I am a rookie programmer. And finally here is the code: Code:
/*******************************************************************************
* FILE NAME: user_routines_fast.c <FRC VERSION>
*
* DESCRIPTION:
* This file is where the user can add their custom code within the framework
* of the routines below.
*
* USAGE:
* You can either modify this file to fit your needs, or remove it from your
* project and replace it with a modified copy.
*
* OPTIONS: Interrupts are disabled and not used by default.
*
*******************************************************************************/
#include "ifi_aliases.h"
#include "ifi_default.h"
#include "ifi_utilities.h"
#include "user_routines.h"
#include "user_Serialdrv.h"
/*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/
int counter=0;
int steering_control=127;
int drive_speed=127;
int steering_adjuster=0;
unsigned char Limit_Mix (int);
#if _USE_CMU_CAMERA
#include "user_camera.h"
/****************************
** VISION VARIABLES **
*****************************/
extern cam_struct cam;
extern int speed_control;
extern int speed_setting;
extern unsigned char cam_uart_buffer[];
unsigned char char_buffer[2]; // 11
volatile unsigned int data_rdy;
volatile unsigned int cam_index_ptr = 0; // Zero start of buffer
unsigned int start_string;
unsigned char rx_char;
int packet_start = 0; // Used to parse packet types
unsigned int parse_mode = 0; // Tells it to look for '\r' instead of T packets
int tracking, pan_position, tilt_position, drive_control = 0;
int last_pan_position,begin_x, begin_y, end_y, i, j = 0;
unsigned int transit_char,trcnt = 0;
#endif
/*******************************************************************************
* FUNCTION NAME: InterruptVectorLow
* PURPOSE: Low priority interrupt vector
* CALLED FROM: nowhere by default
* ARGUMENTS: none
* RETURNS: void
* DO NOT MODIFY OR DELETE THIS FUNCTION
*******************************************************************************/
#pragma code InterruptVectorLow = LOW_INT_VECTOR
void InterruptVectorLow (void)
{
_asm
goto InterruptHandlerLow /*jump to interrupt routine*/
_endasm
}
/*******************************************************************************
* FUNCTION NAME: InterruptHandlerLow
* PURPOSE: Low priority interrupt handler
* If you want to use these external low priority interrupts or any of the
* peripheral interrupts then you must enable them in your initialization
* routine. Innovation First, Inc. will not provide support for using these
* interrupts, so be careful. There is great potential for glitchy code if good
* interrupt programming practices are not followed. Especially read p. 28 of
* the "MPLAB(R) C18 C Compiler User's Guide" for information on context saving.
* CALLED FROM: this file, InterruptVectorLow routine
* ARGUMENTS: none
* RETURNS: void
*******************************************************************************/
#pragma code
#pragma interruptlow InterruptHandlerLow save=PROD /* You may want to save additional symbols. */
void InterruptHandlerLow ()
{
unsigned char int_byte;
if (INTCON3bits.INT2IF && INTCON3bits.INT2IE) /* The INT2 pin is RB2/DIG I/O 1. */
{
INTCON3bits.INT2IF = 0;
}
else if (INTCON3bits.INT3IF && INTCON3bits.INT3IE) /* The INT3 pin is RB3/DIG I/O 2. */
{
INTCON3bits.INT3IF = 0;
}
else if (INTCONbits.RBIF && INTCONbits.RBIE) /* DIG I/O 3-6 (RB4, RB5, RB6, or RB7) changed. */
{
int_byte = PORTB; /* You must read or write to PORTB */
INTCONbits.RBIF = 0; /* and clear the interrupt flag */
} /* to clear the interrupt condition. */
else
{
CheckUartInts(); /* For Dynamic Debug Tool or buffered printf features. */
}
}
/*******************************************************************************
* FUNCTION NAME: User_Autonomous_Code
* PURPOSE: Execute user's code during autonomous robot operation.
* You should modify this routine by adding code which you wish to run in
* autonomous mode. It will be executed every program loop, and not
* wait for or use any data from the Operator Interface.
* CALLED FROM: main.c file, main() routine when in Autonomous mode
* ARGUMENTS: none
* RETURNS: void
*******************************************************************************/
void User_Autonomous_Code(void)
{
/* Initialize all PWMs and Relays when entering Autonomous mode, or else it
will be stuck with the last values mapped from the joysticks. Remember,
even when Disabled it is reading inputs from the Operator Interface.
*/
pwm01 = pwm02 = pwm03 = pwm04 = pwm05 = pwm06 = pwm07 = pwm08 = 127;
pwm09 = pwm10 = pwm11 = pwm12 = pwm13 = pwm14 = pwm15 = pwm16 = 127;
relay1_fwd = relay1_rev = relay2_fwd = relay2_rev = 0;
relay3_fwd = relay3_rev = relay4_fwd = relay4_rev = 0;
relay5_fwd = relay5_rev = relay6_fwd = relay6_rev = 0;
relay7_fwd = relay7_rev = relay8_fwd = relay8_rev = 0;
while (autonomous_mode) /* DO NOT CHANGE! */
{
if (statusflag.NEW_SPI_DATA) /* 26.2ms loop area */
{
Getdata(&rxdata); /* DO NOT DELETE, or you will be stuck here forever! */
/*****************************Autonomous Code**********************************************/
#if _USE_CMU_CAMERA
if (camera_track_update()==1)
{
// Put vision processing here, because we have a good frame!
if (cam.size > 0)
{
tracking = 1; // if yes then set 'tracking' flag
}
else
{
tracking = 0; // if there is no track, clear the flag
}
}
if (counter==1)
{
if (tracking==1)
{
if (cam.tilt_servo < 105)
{
steering_control=cam.pan_servo;
drive_speed=155;
}
else
{
counter++;
}
}
else
{
if (digital_io_08==1)
{
steering_control=155;
drive_speed=155;
}
else
{
steering_control=100;
drive_speed=155;
}
}
}
if(counter==2)
{
//put code for your manipulator here (to make it grab the tetra),
//and when done with manipulations increment the counter (counter++;)
//make sure the manipulator is not obstructing the camera's view when you increment the counter
}
if(counter==4)
{
camera_stop();
camera_init(45,19,121);
camera_auto_servo(1);
camera_find_color(YELLOW);
counter++;
}
if(counter==5)
{
if (tracking==1)
{
if (cam.tilt_servo < 105)
{
steering_control=cam.pan_servo;
drive_speed=155;
}
else
{
counter++;
}
}
else
{
if (digital_io_08==1)
{
steering_control=90;
drive_speed=127;
}
else
{
steering_control=165;
drive_speed=127;
}
}
}
if (counter==6)
{
//put code to place the tetra on the goal here
//make sure the tetra is not supported by the manipulator when you increment the counter
}
if(counter==7)
{
steering_control=127;
drive_speed=127;
}
p1_y = drive_speed; //set forward speed
p1_x = steering_control; //set turning rate
p1_x = 255 - p1_x; //invert turn direction
// Steering Compensation
if (p1_x > 135 && p1_x < 225 && steering_adjuster > 0)
p1_x = p1_x + steering_adjuster;
if (p1_x < 120 && p1_x > steering_adjuster && steering_adjuster > 0)
p1_x = p1_x - steering_adjuster;
pwm11 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm12 = Limit_Mix(2000 + p1_y - p1_x + 127);
#else
pwm11 = pwm12 = 127;
#endif
/************************End Autonomous Mode***********************************/
Generate_Pwms(pwm13,pwm14,pwm15,pwm16);
Putdata(&txdata); /* DO NOT DELETE, or you will get no PWM outputs! */
}
}
}
/*******************************************************************************
* FUNCTION NAME: Process_Data_From_Local_IO
* PURPOSE: Execute user's realtime code.
* You should modify this routine by adding code which you wish to run fast.
* It will be executed every program loop, and not wait for fresh data
* from the Operator Interface.
* CALLED FROM: main.c
* ARGUMENTS: none
* RETURNS: void
*******************************************************************************/
void Process_Data_From_Local_IO(void)
{
#if _USE_CMU_CAMERA
if (counter==0)
{
camera_init(45,19,121);
camera_auto_servo(1);
camera_find_color(GREEN);
counter++;
}
if (speed_setting < 128 || speed_control > 254) //Check speed_setting for valid forward speed
speed_setting = 150; //If not valid number set to default
if (p1_sw_trig > 0){ // RUN ONLY IF TRIGGER IS HELD
if (tracking > 0)
speed_control = speed_setting;
else {
trcnt ++;
if (trcnt > 1000)
speed_control = 127;
else
trcnt = 0;
}
}
if (tracking < 1 && p1_sw_trig < 1){
speed_control = 127;
pan_position = 127;
}
#endif
}
/*******************************************************************************
* FUNCTION NAME: Serial_Char_Callback
* PURPOSE: Interrupt handler for the TTL_PORT.
* CALLED FROM: user_SerialDrv.c
* ARGUMENTS:
* Argument Type IO Description
* -------- ---- -- -----------
* data unsigned char I Data received from the TTL_PORT
* RETURNS: void
*******************************************************************************/
void Serial_Char_Callback(unsigned char tmp)
{
/* Add code to handle incomming data (remember, interrupts are still active) */
#if _USE_CMU_CAMERA
/*******************************************************************************
This is the section of the UART rx interrupt routine that handle the camera
buffer. There are two different modes parse_mode=0 and parse_mode=1.
parse_mode=0
is for reading ACKs back from the camera. It will buffer an entire line until
it reads a '\r' character. It should be used for non streaming data from the
camera.
parse_mode=1
is for reading tracking packets that are streaming from the camera. It assumes
the camera is in raw mode and will read until it gets a 'T' character. It then
buffers until it gets a 255 bytes which in raw mode signifies the end of line.
cam_index_ptr - is the counter that keeps track of the current location in the
buffer.
data_rdy - is a flag that remains 0 until the entire data packet is ready at
which point it becomes 1. Once data_rdy is 1, new packets will be
ignored.
********************************************************************************/
if (data_rdy==0)
{
if (parse_mode==0) // Grab single line packets, such as ACKS or NCKS
{
if (tmp=='\r' || cam_index_ptr==MAX_BUF_SIZE)
{
// Once the end of a packet is found, assert data_rdy and wait
cam_uart_buffer[cam_index_ptr]=0;
data_rdy=1;
}
else
{
cam_uart_buffer[cam_index_ptr]=tmp;
cam_index_ptr++;
}
}
if (parse_mode==1) // Grab streaming packets
{
if (tmp=='T' )
{
data_rdy=0;
cam_uart_buffer[0]=tmp;
cam_index_ptr=1;
return;
}
if (cam_index_ptr>0) // Added this to potentially stop unnecessary delays
{
if (tmp==255 || cam_index_ptr==MAX_BUF_SIZE)
{
if (cam_index_ptr==0 )return;
// Once the end of a packet is found, assert data_rdy and wait
cam_uart_buffer[cam_index_ptr]=0;
data_rdy=1;
}
else
{
cam_uart_buffer[cam_index_ptr]=tmp;
cam_index_ptr++;
}
}
}
}
#endif
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
|
|
#2
|
||||
|
||||
|
I'll try to test that code out for you tommarow It looks awsome to me.
I do see one small thing, maybe, you have this in void Process_Data_From_Local_IO(void) but shouldn't it go in the user initialization? Code:
if (counter==0)
{
camera_init(45,19,121);
camera_auto_servo(1);
camera_find_color(GREEN);
counter++;
}
Let me know if I am also on the right track. I am also a Rookie programmer. |
|
#3
|
|||||
|
|||||
|
Re: Out of the Box Camera Code
Well, I guess it could, but isnt that in user_routines.c? One of my goals with this was to create code that was sort of modular; all you have to do is insert this file into your code and as long as you have all the stuff to support the camera it should work. Also I thought some team might find it handy to be able to reset counter to zero and have that code run again. The reason that bit wasnt in the autonomous section was so the camera can scan before the match starts. I changed one thing since I posted this, and this was that I changed the name of the variable tracking, as tracking is used by the default code and I didnt want this to interfere with that or vice versa. Anyway if you get a chance to test it let me know how it goes. I have a readme file done, so Im gonna try to figure out how to post that without having to quote the whole thing.
Edit: Alright, figured it out. Here is the Readme, along with the most recent version of the code (note that I had to change the file type to .txt in order to attach it. You will have to change it back to .c). Last edited by russell : 18-02-2005 at 00:55. Reason: Added Readme |
|
#4
|
|||
|
|||
|
Re: Out of the Box Camera Code
I tested it as a quick setup to see if the camera would track an whatnot and it works. I had to change a few things, I think for some reason I got a code error without the camera installed, but I fixed that. I couldn't tell you anything I changed right now because my brain hurts... but you did an excellent job. I think this will help many many teams.
|
|
#5
|
||||
|
||||
|
Quote:
I see your thinking, good idea. Thanks for the help |
|
#6
|
|||
|
|||
|
Re: Out of the Box Camera Code
THANX so so so much, i think this code will go a long way for our team. i am a rookie programmer and this will save me a lot of wasted time and headaches, thanx again
![]() |
|
#7
|
|||
|
|||
|
Re: Out of the Box Camera Code
I have a project,use cmucam2 tracking object ( robot tracking object). I use dspic, but when i search on internet,i don't see code about dspic ( or pic) and cmucam2. if you have code, please contact me : lenguyendacan@yahoo.com
|
|
#8
|
||||
|
||||
|
Re: Out of the Box Camera Code
Quote:
This is a pretty old thread and we as an organization haven't used the CMU Cam in a while, check out http://kevin.org/frc/2006/ for reference code. --James |
|
#9
|
|||
|
|||
|
Re: Out of the Box Camera Code
I know cmucam2 is old,so it's hard search code concern it. But, i must finish this project. I hope you will help me.
I don't understand how i can control robot (my robot has 3 wheels, 2dc motor) tracking object using data from CMUcam2. I 'm really needed help |
|
#10
|
||||
|
||||
|
Re: Out of the Box Camera Code
discussion continued in other thread.
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Combined Camera and PID/Encoder Code | Terry Sherman | Programming | 1 | 14-03-2005 17:59 |
| Problem downloading any Camera code | zuckie13 | Programming | 4 | 07-02-2005 20:32 |
| Team THRUST - Kevin's Code and Camera Code Combine | Chris_Elston | Programming | 3 | 31-01-2005 22:28 |
| CMUCam2 Camera Code - Are important parts commented out? | Mr. Lim | Programming | 4 | 14-01-2005 12:11 |
| heres the code. y this not working | omega | Programming | 16 | 31-03-2004 15:18 |