1 / 44

WORKSHOP: PROGRAMMING ENVIRONMENT

WORKSHOP: PROGRAMMING ENVIRONMENT Steve Waldo Programming Mentor, Team 1816 s-waldo@comcast.net Anna W. Team 1816 programming sub-team lead Workshop What you’ll need, and what you’ll need to know, to begin programming your FRC robot ! This presentation adapted from:

jana
Download Presentation

WORKSHOP: PROGRAMMING ENVIRONMENT

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. WORKSHOP:PROGRAMMING ENVIRONMENT Steve Waldo Programming Mentor, Team 1816s-waldo@comcast.net Anna W. Team 1816 programming sub-team lead

  2. Workshop What you’ll need, andwhat you’ll need to know,to begin programming your FRC robot !

  3. This presentation adapted from: "Introduction to C Programming for FIRST " PowerPoint presentations by David Maxwell Available for download at: http://www.usfirst.org/community/frc under the tabs Team Resources > Programming

  4. You need 5 things: • MPLAB software • IDE (Integrated Development Environment) [EDITOR] • C18 (C program compiler) [Translates your program into machine instructions] • http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en019469&part=SW007002 • FRC default C source code (FIRSTRobotics Competition) • IFI Loader (Innovation First, Inc.) • You can download 2. default code and 3. IFI_Loader from http://www.ifirobotics.com/rc.shtml (scroll to bottom) • A PC running Windows • A serial cable from a serial or USB port on your PC to the programming port on the Robot Controller (RC).

  5. Also: WPILib Simplified Robot Controller Programming available at this web site: http://users.wpi.edu/~bamiller/WPILib/

  6. Overview of Programming Process Just once: • Obtain and read instructions from IFI • Obtain default code, and IFI Loader e.g. from IFI website http://www.ifirobotics.com/rc.shtml • Obtain MPLAB IDE and C18 e.g. fromwww.microchip.com • Install MPLAB, and IFI_Loader on your PC Henceforth: • Write and compile your code: Run MPLAB, edit (a copy of) code, and compile the code – this creates a .hex file • Download your code to your Robot Contoller: Run IFI Loader to transfer the .hex file to your RC

  7. 1. To write and compile your code • Start MPLAB IDE • File -> Open Workspace… • Select the .mcw file from the Default Code you downloaded. • Double-click user_routines.c in project window. • Scroll down and edit Default_Routine(). • Menu: Project -> Make (or button) • Verify you get a “BUILD SUCCEEDED” message

  8. An example code change: pwm01 = p1_y; pwm02 = p2_y; pwm03 = p3_y; pwm04 = p4_y; pwm05 = p1_x; pwm06 = p2_x; pwm07 = p3_x; pwm08 = p4_x; original pwm01 = p1_y; pwm02 = p1_x; pwm03 = p3_y; pwm04 = p4_y; pwm05 = p1_x; pwm06 = p2_x; pwm07 = p3_x; pwm08 = p4_x; I could change to:

  9. 2. To download code to your Robot Controller • Power up the Robot Controller (RC) • Connect serial cable from PC to PROGRAM port. • Start IFI_Loader on your PC. • Select appropriate COM port (for your serial cable). • “Browse” to find the .hex file you just compiled. • Click DOWNLOAD – after the download is complete, the program will automatically begin to execute on the RC if you are linked to an operator interface. • For SAFETY: have robot’s wheels in air the first time!

  10. C Concepts The very basics…

  11. One project, many files… • .c -Source Files • .h -Header Files • .lib -Library Files • .lkr -Linker Scripts • Edit the .c and .h files • Compile • Link  FrcCode.hex

  12. Variables unsigned char wheel_count; /* range: 0 to 255 */ char wheel_count; /* range: -128 to 127 */ unsigned int wheel_count; /* range: 0 to 65535 */ int wheel_count; /* range: -32768 to 32767 */ Tip: choose variable names others on your team will easily understand Tip: put lots of explanatory comments into your source files /* This is a comment. It is ignored by the compiler. It ends here. */

  13. C is case-sensitive unsigned char wheel_count; (is not the same as) unsigned char Wheel_count;

  14. Functions (also known as subroutines) three_doubled = Double_Number(3); Tip: use functions (subroutines) wherever you can … so if you need to make a change, you only have to make the change in one place…

  15. Example Function LOCAL NAME FOR INPUT VARIABLE TYPE OF ANSWER RETURNED TYPE OF INPUT GIVEN FUNCTION NAME unsigned int Doubled_Number (unsigned int num2double) { unsigned int result; result = 2 * num2double; return result; }

  16. LOCAL VARIABLES RETURN VALUE Example Function • unsigned int Doubled_Number (unsigned int num2double) • { • unsigned int result; • result = 2 * num2double; • return result; • } INSTRUCTIONS TO EXECUTE

  17. Simplest Function • void Do_Nothing(void) • { • return; • }

  18. Function Prototypes(go into a header [ .h ] file) unsigned int Double_Number (unsigned int num2double); void Do_Nothing (void);

  19. MUST be in left-most column! Pre-Processor Note The # symbol denotes a pre-processor statement that is evaluated before the compiler takes over. #include “ifi_aliases.h”

  20. Macros as aliases(easier names for more complex expressions) #define p4_sw_aux2 rxdata.oi_swB_byte.bitselect.bit7 /* Auxiliary input*/

  21. Macros (as constants) #define FIELD_WIDTH 125 #define FIELD_LENGTH 300 #define FIELD_PERIMETER (FIELD_WIDTH*2 + FIELD_LENGTH*2) Use provided constants found in: ifi_aliases.h Put yours in: user_routines.h Tip: use constants wherever you can instead of “raw numbers” … so if you need to make a change, you only have to make the change in one place…and so you remember what the number is for. Tip: make constants’ names ALL CAPS so they are easily recognized by others as constants wherever seen in your program

  22. Assignment statements relay3_fwd = p3_sw_trig; Note that instructions in the C programming language end with a semicolon

  23. Comparison and Logical Operators + - * / add subtract multiply divide && || & | and or bit-wise and bit-wise or > >= < <= greater greater less than less thanthan or equal to or equal to == != equal not equal Tip: Don’t use = (assignment) when you mean == (test of equality)

  24. if ( LOGICAL CONDITION 1 ) { DO THIS } else if ( LOGICAL CONDITION 2 ) { DO THIS } else { DO THIS BY DEFAULT } Conditionals (decision-making)

  25. Looping: while while(condition is TRUE) { execute these instructions } The while loop repeats a statement until the test at the top proves false. count = 0; while(count < 7) { count = count + 1;} Example:

  26. Looping: while • This is an infinite loop. while(1) { /* do this forever */ }

  27. Debugging : the print function printf pwm01 = 125 + 2; printf(“PWM01 = %d\n”,(int)pwm01); If you have the serial cable connected from your robot controller to your PC, and then you can see this output in the Terminal Window in IFI_Loader: PWM01 = 127 Tip: Use printf statements liberally when writing and testing any new part of your program.

  28. Default Code Explained C by example…

  29. Program Flow

  30. You only need to edit the three files that start with “user_”. Which files do you care about? • To follow the flowchart we’ll be looking inside: • main.c • user_routines.c • user_routines_fast.c

  31. Step-by-Step Walkthrough void main (void) { IFI_Initialization (); /* DO NOT CHANGE! */ User_Initialization(); /* You edit this in user_routines.c */ while (1) /* This loop will repeat indefinitely. */ { if (statusflag.NEW_SPI_DATA) /* 26.2ms loop area */ { Process_Data_From_Master_uP(); /* You edit this in user_routines.c */ if (autonomous_mode) /* DO NOT CHANGE! */ { User_Autonomous_Code(); /* You edit this in user_routines_fast.c */ } } Process_Data_From_Local_IO(); /* You edit this in user_routines_fast.c */ /* I'm fast! I execute during every loop.*/ } /* while (1) */ } /* END of Main */ main.c

  32. void User_Initialization (void) { rom const char *strptr = "IFI User Processor Initialized ..."; Set_Number_of_Analog_Channels(SIXTEEN_ANALOG); /* DO NOT CHANGE! */ /* FIRST: Set up the I/O pins you want to use as digital INPUTS. */ digital_io_01 = digital_io_02 = digital_io_03 = digital_io_04 = INPUT; digital_io_05 = digital_io_06 = digital_io_07 = digital_io_08 = INPUT; digital_io_09 = digital_io_10 = digital_io_11 = digital_io_12 = INPUT; digital_io_13 = digital_io_14 = digital_io_15 = digital_io_16 = INPUT; digital_io_18 = INPUT; /* Used for pneumatic pressure switch. */ /* SECOND: Set up the I/O pins you want to use as digital OUTPUTS. */ digital_io_17 = OUTPUT; /* Example - Not used in Default Code. */ /* THIRD: Initialize the values on the digital outputs. */ rc_dig_out17 = 0; /* FOURTH: Set your initial PWM values. Neutral is 127. */ pwm01 = pwm02 = pwm03 = pwm04 = pwm05 = pwm06 = pwm07 = pwm08 = 127; pwm09 = pwm10 = pwm11 = pwm12 = pwm13 = pwm14 = pwm15 = pwm16 = 127; /* FIFTH: Set your PWM output types for PWM OUTPUTS 13-16. */ Setup_PWM_Output_Type(IFI_PWM,IFI_PWM,IFI_PWM,IFI_PWM); /* Add any other initialization code here. */ Initialize_Serial_Comms(); Putdata(&txdata); /* DO NOT CHANGE! */ printf("%s\n", strptr); User_Proc_Is_Ready(); /* DO NOT CHANGE! - last line of User_Initialization */ } User_Initialization();in user_routines.c

  33. Step-by-Step Walkthrough void main (void) { IFI_Initialization (); /* DO NOT CHANGE! */ User_Initialization(); /* You edit this in user_routines.c */ while (1) /* This loop will repeat indefinitely. */ { if (statusflag.NEW_SPI_DATA) /* 26.2ms loop area */ { Process_Data_From_Master_uP(); /* You edit this in user_routines.c */ if (autonomous_mode) /* DO NOT CHANGE! */ { User_Autonomous_Code(); /* You edit this in user_routines_fast.c */ } } Process_Data_From_Local_IO(); /* You edit this in user_routines_fast.c */ /* I'm fast! I execute during every loop.*/ } /* while (1) */ } /* END of Main */ main.c

  34. Process_Data_From_Master_uP();in user_routines.c /****************************************************************** * FUNCTION NAME: Process_Data_From_Master_uP * PURPOSE: Executes every 26.2ms when it gets new data from the master * microprocessor. * CALLED FROM: main.c * ARGUMENTS: none * RETURNS: void *******************************************************************/ void Process_Data_From_Master_uP(void) { Getdata(&rxdata); /* Get fresh data from the master microprocessor. */ Default_Routine(); /* Optional. See below. */ /* Add your own code here. */ printf("PWM1 %3d, PWM2 %3d\n",(int)pwm01,(int)pwm02); /* printf EXAMPLE */ Generate_Pwms(pwm13,pwm14,pwm15,pwm16); Putdata(&txdata); /* DO NOT CHANGE! */ }

  35. Step-by-Step Walkthrough void main (void) { IFI_Initialization (); /* DO NOT CHANGE! */ User_Initialization(); /* You edit this in user_routines.c */ while (1) /* This loop will repeat indefinitely. */ { if (statusflag.NEW_SPI_DATA) /* 26.2ms loop area */ { Process_Data_From_Master_uP(); /* You edit this in user_routines.c */ if (autonomous_mode) /* DO NOT CHANGE! */ { User_Autonomous_Code(); /* You edit this in user_routines_fast.c */ } } Process_Data_From_Local_IO(); /* You edit this in user_routines_fast.c */ /* I'm fast! I execute during every loop.*/ } /* while (1) */ } /* END of Main */ main.c

  36. INPUTS OUTPUTS Default_Routine();- PWM Mapping /******************************************************************** * FUNCTION NAME: Default_Routine * PURPOSE: Performs the default mappings of inputs to outputs. * CALLED FROM: this file, Process_Data_From_Master_uP routine * ARGUMENTS: none * RETURNS: void ------------------------------------------------------------------------------*/ void Default_Routine(void) { /*---------- Analog Inputs (Joysticks) to PWM Outputs----------------------- *-------------------------------------------------------------------------- * This maps the joystick axes to specific PWM outputs. */ pwm01 = p1_y; pwm02 = p2_y; pwm03 = p3_y; pwm04 = p4_y; pwm05 = p1_x; pwm06 = p2_x; pwm07 = p3_x; pwm08 = p4_x; pwm09 = p1_wheel; pwm10 = p2_wheel; pwm11 = p3_wheel; pwm12 = p4_wheel; ifi_aliases.hcontains all of these macro definitions and more… unsigned char Range: 0 to 255

  37. Default_Routine();- 1 Joystick Drive /*---------- 1 Joystick Drive ---------------------------------------------- *-------------------------------------------------------------------------- * This code mixes the Y and X axes on Port 1 to allow one joystick drive. * Joystick forward = Robot forward * Joystick backward = Robot backward * Joystick right = Robot rotates right * Joystick left = Robot rotates left * Connect the right drive motors to PWM13 and/or PWM14 on the RC. * Connect the left drive motors to PWM15 and/or PWM16 on the RC. */ pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127); pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);

  38. Default_Routine();- Buttons to Relays /*---------- Buttons to Relays---------------------------------------------- *-------------------------------------------------------------------------- * This default code maps the joystick buttons to specific relay outputs. * Relays 1 and 2 use limit switches to stop the movement in one direction. * The & used below is the C symbol for AND */ relay1_fwd = p1_sw_trig & rc_dig_in01; /* FWD only if switch1 is not closed. */ relay1_rev = p1_sw_top & rc_dig_in02; /* REV only if switch2 is not closed. */ relay2_fwd = p2_sw_trig & rc_dig_in03; /* FWD only if switch3 is not closed. */ relay2_rev = p2_sw_top & rc_dig_in04; /* REV only if switch4 is not closed. */ relay3_fwd = p3_sw_trig; relay3_rev = p3_sw_top; relay4_fwd = p4_sw_trig; relay4_rev = p4_sw_top; relay5_fwd = p1_sw_aux1; relay5_rev = p1_sw_aux2; relay6_fwd = p3_sw_aux1; relay6_rev = p3_sw_aux2; relay7_fwd = p4_sw_aux1; relay7_rev = p4_sw_aux2; relay8_fwd = !rc_dig_in18; /* Power pump only if pressure switch is off. */ relay8_rev = 0; ifi_aliases.hlists these aliases

  39. Default_Routine();- Limit Switches /*---------- PWM outputs Limited by Limit Switches ---------*/ Limit_Switch_Max(!rc_dig_in05, &pwm03); Limit_Switch_Min(!rc_dig_in06, &pwm03); Limit_Switch_Max(!rc_dig_in07, &pwm04); Limit_Switch_Min(!rc_dig_in08, &pwm04); Limit_Switch_Max(!rc_dig_in09, &pwm09); Limit_Switch_Min(!rc_dig_in10, &pwm09); Limit_Switch_Max(!rc_dig_in11, &pwm10); Limit_Switch_Min(!rc_dig_in12, &pwm10); Limit_Switch_Max(!rc_dig_in13, &pwm11); Limit_Switch_Min(!rc_dig_in14, &pwm11); Limit_Switch_Max(!rc_dig_in15, &pwm12); Limit_Switch_Min(!rc_dig_in16, &pwm12); void Limit_Switch_Max(unsigned char switch_state, unsigned char *input_value) { if (switch_state == CLOSED) { if(*input_value > 127) *input_value = 127; } }

  40. Default_Routine();- Feedback LEDs I /*---------- ROBOT FEEDBACK LEDs------------------------------------------------ *------------------------------------------------------------------------------ * This section drives the "ROBOT FEEDBACK" lights on the Operator Interface. * The lights are green for joystick forward and red for joystick reverse. * These may be changed for any use that the user desires. */ if (user_display_mode == 0)/* User Mode is Off */ {/* Check position of Port 1 Joystick */ if (p1_y >= 0 && p1_y <= 56) {/* Joystick is in full reverse position */ Pwm1_green = 0;/* Turn PWM1 green LED - OFF */ Pwm1_red = 1;/* Turn PWM1 red LED - ON */ } else if (p1_y >=125 && p1_y <= 129) {/* Joystick is in neutral position */ Pwm1_green = 1;/* Turn PWM1 green LED - ON */ Pwm1_red = 1;/* Turn PWM1 red LED - ON */ } else if (p1_y >= 216 && p1_y <= 255) {/* Joystick is in full forward position*/ Pwm1_green = 1;/* Turn PWM1 green LED - ON */ Pwm1_red = 0;/* Turn PWM1 red LED - OFF */ } else {/* In either forward or reverse position */ Pwm1_green = 0;/* Turn PWM1 green LED - OFF */ Pwm1_red = 0;/* Turn PWM1 red LED - OFF */ }/*END Check position of Port 1 Joystick

  41. Default_Routine();- Feedback LEDs II /* This drives the Relay 1 and Relay 2 "Robot Feedback" lights on the OI. */ Relay1_green = relay1_fwd; /* LED is ON when Relay 1 is FWD */ Relay1_red = relay1_rev; /* LED is ON when Relay 1 is REV */ Relay2_green = relay2_fwd; /* LED is ON when Relay 2 is FWD */ Relay2_red = relay2_rev; /* LED is ON when Relay 2 is REV */ Switch1_LED = !(int)rc_dig_in01; Switch2_LED = !(int)rc_dig_in02; Switch3_LED = !(int)rc_dig_in03; }/* (user_display_mode = 0) (User Mode is Off) */ else/* User Mode is On - displays data in OI 4-digit display*/ { User_Mode_byte = backup_voltage*10;/* so that decimal doesn't get truncated. */ } } /* END Default_Routine(); */

  42. Places to modify: in:user_routines.c • Add variables • Initialization • Modify Default_Routine() • Add to slow loop • Add to fast loop • Add to Autonomous code in:user_routines_fast.c

  43. Key Documents to Read! • From Innovation First website: • 2004 Full-Size Control System Quick Start Guide for the OI and Full-Size RC [6 pages] • 2004 Programming Reference Guide 4/12/2004 [29 pages] • www.innovationfirst.com/firstrobotics/documentation • From www.cs.cmu.edu/~camcam • CMUcam2 manual

  44. Resources • http://innovationfirst.com/FIRSTRobotics • http://www.microchip.com • Kernighan, Brian W. and Ritchie, Dennis. The C Programming Language (2nd Edition) [about $33 to $41 at Amazon.com]

More Related