Project 1: SunPass

Note: This assignment is used to assess the required outcomes for the course, as outlined in the course syllabus. These outcomes are:

  1. use of arrays and pointers in the solution of programming problems using C++
  2. create and use classes within the C++ programming language
  3. create, compile, and execute C++ programs within the Unix environment, using the Object-Oriented design model
  4. program using C++ techniques: composition of objects, operator overloads, dynamic memory allocation, inheritance and polymorphism, and file I/O
  5. program using C++ techniques: composition of objects, templates, preprocessor directives, and basic data structures.

These will be assessed using the following rubric:

Rubric for Outcomes i.-iv. I E H  
Key:
  I = ineffective
  E = effective
  H = highly effective
i. Use Arrays and Pointers - - -
ii. Use Classes and Objects - - -
iii. OO Programming Techniques - - -
iv. Inheritance and Polymorphism - - -

In order to earn a course grade of C- or better, the assessment must result in Effective or Highly Effective for each outcome.

Educational Objectives: After completing this assignment the student should have the following knowledge, ability, and skills:

Operational Objectives: Create (define and implement) classes Box, Cylinder, Plane, Vehicle, Car, Truck, Van, Tanker, and Flatbed and an object-oriented vehicle counter for use by the Department of Transportation (DOT).

Deliverables: Seven (7) files: vehicles.h, vehicles.cpp, shapes.h, shapes.cpp, verbose.cpp, tracker.cpp, and makefile.

The SunPass Tracker Project

This project simulates an application called tracker for the Florida Turnpike Authority in which data from SunPass transponders is accumulated in real time using various sensing equipment. The sensors detect a SunPass-equiped vehicle and actively inquire further data when that vehicle is a truck. (The data is used, among other things, to charge a passage toll on the vehicle's SunPass account, thus eliminating the need to stop at toll booths. SunPass is valid on all toll roads and bridges in Florida.) For all vehicles a serial number is collected. The serial number can be decoded to determine the vehicle type (car, truck/van, truck/tanker, truck/flatbed), passenger capacity, and, for trucks, the dimensions of its carrier. Trucks actively respond with their DOT license number as well.

Tracker is set up at a specific point on a roadway, near a toll booth or a specific segment of limited access highway. Once activated, it keeps a running account of the SunPass equipped passing vehicles. It can report summary data and also can keep full reports of all vehicles passing the checkpoint within a certain time block. It also keeps track of individual toll charges and can produce a summary of the charges accumulated in a segment.

Procedural Requirements

  1. Create and work within a separate subdirectory cop3330/proj1. Review the COP 3330 rules found in Introduction/Work Rules.

  2. Begin by copying the following files from the course directory: into your proj1 directory:

    proj1/tester.cpp
    proj1/segment0.data
    proj1/segment1.data
    proj1/segment2.data
    proj1/makefile
    proj1/proj1submit.sh
    area51/tester_s.x
    area51/tester_i.x
    area51/tester_bad_i.x
    area51/tracker_s.x
    area51/tracker_i.x
    

    The naming of these files uses the convention that _s and _i are compiled from the same cource code on program (Sun/Solaris) and linprog (Intel/Linux), respectively. The area51 files are distributed only for your information, experimentation, and testing. You will not need these files in your own project.

  3. You are to define and implement the following classes: Box, Cylinder, Plane, Vehicle, Car, Truck, Van, Tanker, and Flatbed.

  4. File shapes.h should contain the definitions of the classes Box, Cylinder, and Plane. File shapes.cpp should contain the member function implementations for these classes.

  5. File vehicles.h should contain the definitions of the classes Vehicle, Car, Truck, Van, Tanker, and Flatbed. File vehicles.cpp should contain the implementations for these classes.

  6. File verbose.cpp should contain the verbose versions of the various class implementations (both shapes and vehicles).

  7. Create a client program for all of these classes in the file tracker.cpp.

  8. Create a makefile for all of the project in the file makefile.

  9. Turn in all seven (7) files vehicles.h, vehicles.cpp, shapes.h, shapes.cpp, verbose.cpp, tracker.cpp, and makefile using the proj1submit.sh submit script.

    Warning: Submit scripts do not work on the program and linprog servers. Use shell.cs.fsu.edu to submit projects. If you do not receive the second confirmation with the contents of your project, there has been a malfunction.

Code Requirements and Specifications - Server Side

  1. You are to define and implement the following classes:

    Class Name:
      Box
    Services (added or changed): 
      float Volume() const // returns volume of box object  
    
    Private variables:
      float length_, width_, height_

    Class Name:
      Cylinder
    Services (added or changed): 
      float Volume() const // returns volume of cylinder object  
    
    Private variables:
      float length_, radius_

    Class Name:
      Plane
    Services (added or changed): 
      float Area() const // returns area of plane object  
    
    Private variables:
      float length_, width_

    Class Name:
      Vehicle
    Services (added or changed): 
      const char*           SerialNumber       () const // returns serial number 
      unsigned int          PassengerCapacity  () const // returns passenger capacity 
      float                 LoadCapacity       () const // returns 0
      const char*           ShortName          () const // returns "UNK"
      float                 Toll               () const // returns toll using fee schedule
      static  VehicleType   SnDecode           (const char* sn)
    
    Private variables:
      char*        serialNumber_;
      unsigned int passengerCapacity_;
    

    Class name:
      Car
    
    Inherits from:
      Vehicle
    
    Services (added or changed): 
      const char* ShortName() const // returns "CAR"  
    

    Class name:
      Truck
    
    Inherits from:
      Vehicle  
    
    Services (added or changed): 
      const char*   ShortName          () const  // returns "TRK"
      float         Toll               () const  // returns toll using fee schedule
      const char*   DOTLicense         () const  // returns the license no  
    
    Private variables:
      char* DOTLicense_; 
    

    Class name:
      Van
    
    Inherits from:
      Truck , Box  
    
    Services (added or changed): 
      float         LoadCapacity       () const  // returns volume of box  
      const char*   ShortName          () const  // returns "VAN"
    

    Class name:
      Tanker
    
    Inherits from:
      Truck , Cylinder  
    
    Services (added or changed): 
      float         LoadCapacity       () const  // returns volume of cylinder  
      const char*   ShortName          () const  // returns "TNK"
    

    Class name:
      Flatbed
    
    Inherits from:
      Truck , Plane  
    
    Services (added or changed): 
      float         LoadCapacity       () const  // returns area of plane  
      const char*   ShortName          () const  // returns "FLT"  
    

  2. Each class should have the following:

    1. Default constructor
    2. Parametrized constructor that initializes the class variables
    3. Destructor
    4. Private copy constructor prototype
    5. Private assignment operator prototype
    6. Follow the notation conventions:
      1. Compound names use uppercase letters to separate words likeThis or LikeThis
      2. Class, method, and function names begin with upper case letters LikeThis
      3. Object and variable names names begin with lower case letters likeThis
      4. Class member variables end with underscore likeThis_
  3. Be sure to make exactly the methods virtual that are needed - that is, those that are overridden in derived classes. Do not make a method virtual unless it is needed virtual.

  4. The toll fee schedule is:
    minimum for all vehicles: $2.00
    all trucks: $10.00

  5. During development and testing of the classes, each constructor and destructor should include a line of code that sends an identifying message to standard output. (This requirement serves as a code testing device. These identifying output statements will be removed after development. But leave them in verbose.cpp when you submit!) For example, the Van destructor should output the message "~Van()".

  6. The user-defined type VehicleType is an enumerated type:

    Type name:
      VehicleType
    
    Enumerated values:
      badSn, vehicle, car, truck, van, tanker, flatbed  
    

  7. The static method VehicleType Vehicle::SnDecode(const char* sn) returns the vehicle type based on the first (index 0) character of the serial number sn according to this table:

          sn[0]: 0        1        2        3        4        5        6
    VehicleType: badSn    vehicle  car      truck    van      tanker   flatbed  
    

  8. After your classes have been fully developed and debugged, so they compile without warnings using the commands g++ -c -I. -Wall -Wextra shapes.cpp and g++ -c -I. -Wall -Wextra vehicles.cpp, it is time to test with tester.cpp:

    1. Concatenate the files shapes.cpp and vehicles.cpp into the file verbose.cpp [command: cat shapes.cpp vehicles.cpp > verbose.cpp]. Add file documentation to verbose.cpp as usual.
    2. #include shapes.h and vehicles.h into verbose.cpp, between your file documentation and the beginning of the code.
    3. Make sure that verbose.cpp compiles to object code with our usual compile command g++ -c -Wall -Wextra -I. verbose.cpp.
    4. Now build the executable program tester.x with this command: make tester.x
    5. Thoroughly test your vehicle objects with this program. Note that this program prompts you for a serial number. The serial number is decoded to get a vehicle type, and an object of that type is created dynamically. You should see the constructor calls displayed, in correct order, because tester uses the verbose versions of your classes. Then the methods of this object are called. You should see correct serial number (and, for trucks, dot license) displayed. An "OOPS" message will be displayed if a problem is detected with your constructors. Finally the object is deleted, and you should see the destructors called in correct order. Read the source code in tester.cpp both to understand how it works and also for hints on how to do certain things in tracker.cpp.
  9. After you have developed and thoroughly tested your Vehicles classes as above, it is time to prepare your classes for Tracker:

    1. Comment out the verbose output statements in the constructors and destructors in shapes.cpp and vehicles.cpp, but leave them in verbose.cpp
    2. We are now ready to proceed to client side development.

Code Requirements and Specifications - Client Side

  1. You are to implement a client program tracker of the vehicle system described above.

  2. Tracker processes data from a file that is input through redirection and sends results to standard output. (Thus tracker does not deal directly with files but reads from and writes to standard I/O.)

  3. Tracker goes through the following processing loop:

    1. Read the number of vehicles in the next segment
    2. If the number is zero, exit
    3. For each vehicle in the segment,
      1. Decode the vehicle serial number
      2. If other data is needed, read that data
      3. Create a vehicle of the appropriate type using the data read in the previous steps
      4. Update various summary information for this segment
    4. After all the vehicles in the segment have been read and their corresponding objects created, report a summary of the various vehicles by type, along with the totals of tonnage and tolls of the segment.
    5. After the summary, report the details: for each vehicle in the segment:
      1. Report the vehicle data to screen
      2. Release the memory used to store the vehicle
    When in doubt, use the distributed area51 executables as a guide to output data and formatting.

  4. Note that the tracker processing loop continues until zero is read for a segment size. It may be assumed that the file of data is correctly structured so that whenever an appropriate item is expected, it is next in the file. For all vehicles, the data will begin with the serial number sn and then give the passenger capacity pc. For all specific truck types, the next entry will be the DOTlicense DOTL followed by the dimension data d1 d2 d3(optional). For example, a car, truck, van, tanker, and flatbed would have these lines of data:

    sn pc
    sn pc DOTL
    sn pc DOTL d1 d2 d3
    sn pc DOTL d1 d2
    sn pc DOTL d1 d2
    

    The dimensional data should be interpreted in the order d1 = length, d2 = width or radius, d3 = height. Note that this is more or less self-documenting in the data file segment0.data. Note also that we will assume that each vehicle and its data are in a separate line of the input file.

  5. Tracker should instantiate the objects of a segment using an array whose elements are of type Vehicle *, that is, pointer to type Vehicle. At the end of reading the segment data, this array should have pointers to vehicle objects representing the entire segment. These objects should exist until the line in the report representing the object is generated.

  6. Use declared constants (not hardcoded literal values) for the following:

    1. The maximum number of vehicles in a traffic segment (100)
    2. The maximum number of characters in a vehicle serial number (20)
    3. The maximum number of characters in a truck DOT license (20)

  7. Check for a segment size greater than tracker can handle, and exit if that happens. Thus tracker would exit if either size 0 is read or some size greater than the declared constant 6.i above.

  8. Your tracker.cpp source file should #include <vehicles.h>, but not any of the other project files. The distributed makefile should create separate object files vehicles.o, shapes.o , and tracker.o and then create the executable tracker.x.

  9. Do not submit "verbose" classes for tracker.

Hints