View Single Post
  #2   Spotlight this post!  
Unread 12-10-2007, 11:41
Alan Anderson's Avatar
Alan Anderson Alan Anderson is offline
Software Architect
FRC #0045 (TechnoKats)
Team Role: Mentor
 
Join Date: Feb 2004
Rookie Year: 2004
Location: Kokomo, Indiana
Posts: 9,113
Alan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond repute
Re: Architecture for software

When I came on board as the programming mentor for the TechnoKats in 2004, I didn't know anything about the IFI control system. I did have some clear ideas on software architecture, and they fortunately turned out to match the way things were set up in the system. I have three basic pieces of advice for everyone who starts with the default code.

First, make good use of abstractions. Don't write code that directly names joystick input pins and pwm output pins. Instead, use aliases like this:
Code:
#define OI_LeftDrive			p3_y
#define OI_RightDrive			p4_y
#define RC_DIG_Pressure			rc_dig_in09
#define RC_RLY_Compressor		relay6_fwd
#define RC_PWM_LeftFront_CIM		pwm09
#define RC_PWM_LeftRear_CIM		pwm10
#define RC_PWM_RightFront_CIM		pwm11
#define RC_PWM_RightRear_CIM		pwm12

Second, try to split the functions that read the operator inputs from the functions that set the motor and relay outputs, and try to keep both of them distinct from the functions that turn inputs into outputs. Put all your OI stuff in the equivalent of Default_Routine(), and keep track of what your operators are requesting in a global variable structure containing things like desired speed, desired turn rate, desired arm position, etc. Put all your motor control stuff in Process_Data_From_Local_IO(), basing the outputs on what's in that global variable structure. Put the code that decides how to change from what the robot is doing now to what it's supposed to do next in a separate function that manipulates the global structure based on robot sensors. It might seem inefficient to do it that way, but it permits a lot of flexibility, and the RC has plenty of power.

Finally, try to keep separate tasks in separate functions, but try to keep everything relating to a specific robot subsystem together. Our 2007 program has functions like Read_OI_Input() and Write_OI_Feedback() in the user_routines.c file, and process_feedback(), process_drivebase(), and process_arm() in user_routines_fast.c.