0% found this document useful (0 votes)
2 views6 pages

Homeworks - Homeworks

Uploaded by

slayerslay45
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views6 pages

Homeworks - Homeworks

Uploaded by

slayerslay45
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

MKT1142 - Homework 4: Modularity, Functions, and Scope (Part 1)

Instructions: Write a separate .cpp file for each question.

Question 1: The Robotic Arm Actuator (Difficulty: Easy - void Functions)

Scenario: You are programming a 3-axis industrial robotic arm. Instead of copying and pasting
the motor control code every time the arm needs to move, you will create a reusable software
module (a function) that acts as the universal motor driver.

Your Task:

1. Above your main() function, define a void function named moveJoint.


2. This function must accept two parameters (inputs): int jointID (which motor to move:
1, 2, or 3) and float targetAngle.
3. Inside the moveJoint function, simply print: "Actuating Joint [jointID] to
[targetAngle] degrees."
4. Inside your main() function, ask the user to input an angle for the Base (Joint 1), the
Shoulder (Joint 2), and the Elbow (Joint 3).
5. Call your moveJoint function three separate times inside main(), passing the respective
Joint IDs and the user's angles.

Engineering Concept: This is how hardware libraries are built. You write the complex actuation
logic once inside a function, and the rest of the program just calls that function, keeping the main
loop clean and readable.

Question 2: The ADC Voltage Converter

Scenario: Microcontrollers (like an Arduino) cannot read "Volts" directly. They use an Analog-
to-Digital Converter (ADC) that outputs a raw integer from 0 to 1023. To use this data in a
physics equation, the software must convert this raw integer back into a real Voltage
(0.0 to 5.0 Volts).

Your Task:

1. Above your main() function, define a function named adcToVoltage that returns
a float and accepts one parameter: int rawADC.
2. Inside the function, calculate the voltage. (Formula: Voltage = (rawADC / 1023.0) * 5.0).
3. Crucial: Use the return keyword to send this calculated float back to the system. Do
not cout (print) anything inside this function!
4. Inside your main() function, write a while(true) loop that continuously asks the user
for a raw ADC value.
5. If the user enters -1, break the loop.
6. Otherwise, call your adcToVoltage function, store the returned value in a local variable,
and print "Converted Sensor Reading: [value] Volts" from inside main().
Engineering Trap: A sensor processing function should NEVER print to the screen. It should
only return raw math. If you put cout inside adcToVoltage, you cannot use that function
silently in a background calculation later. It breaks the concept of modularity.

Question 3: The Reactor Safety Override

Scenario: You are writing the safety monitor for a chemical reactor. The system uses a Global
Variable to trigger a factory-wide alarm if pressure gets too high.

Your Task:

1. Define a global boolean variable bool meltdownAlarm = false; at the very top of your
code (outside of all functions, above main).
2. Define a void function named checkPressure(float currentPressure).
3. Inside this function, if currentPressure is strictly greater than 150.0,
set meltdownAlarm = true; and print "SENSOR: Critical pressure detected!
Tripping global alarm!"
4. Inside your main() function, create a while loop that asks the user for pressure.
5. Call checkPressure() inside the loop.
6. After the function call, check the global variable. If meltdownAlarm == true,
print "MAIN SYSTEM: Alarm active! Shutting down reactor!" and break the loop.

The "Shadowing" Trap: Junior engineers often accidentally redefine global variables locally. Try
this to see the trap:Inside your checkPressure function, if you write bool meltdownAlarm =
true; (adding the word bool), you are creating a brand new, temporary local variable that dies
as soon as the function ends. The global alarm will remain false, the main loop will never know
about the danger, and the reactor will explode. Ensure you do not use the word bool again
when changing the global variable!

Question 4: Differential Drive Kinematics (Difficulty: Hard - Pass-by-Reference &)

Scenario: You are programming the motor control unit for a two-wheeled autonomous delivery
robot (Differential Drive). A standard return function can only output one single value.
However, to steer the robot, your algorithm must calculate and output TWO separate motor
speeds (Left RPM and Right RPM) simultaneously from a single mathematical function.

Your Task:

1. Above main(), define a void function named calculateMotorSpeeds.


2. The function must accept four parameters:
o float targetSpeed (Input)
o float turnOffset (Input: positive for right turn, negative for left turn)
o float &leftRPM (Output - passed by reference!)
o float &rightRPM (Output - passed by reference!)
3. Inside the function, calculate the wheel speeds:
o leftRPM = targetSpeed + turnOffset;
o rightRPM = targetSpeed - turnOffset;
4. Inside your main() function, declare two local variables: float myLeftMotor =
0.0; and float myRightMotor = 0.0;.
5. Ask the user to input a target speed and a turn offset.
6. Call the calculateMotorSpeeds function, passing your local variables.
7. Finally, print the updated myLeftMotor and myRightMotor values from inside main().

Engineering Trap: If you forget to use the ampersand (&) in the function definition, you are using
"Pass-by-Value." The function will create temporary copies of the motor variables, update the
copies, and then destroy them. The real motors (myLeftMotor and myRightMotor in main) will
remain at 0.0, and your robot will never move.

Question 5: Robotic Arm Inverse Kinematics (Difficulty: Very Hard - <cmath> &
Prototypes)

Scenario: You are programming the targeting system for a robotic laser cutter. The user inputs a
target (X, Y) coordinate on the metal sheet. The microcontroller must calculate the physical
distance to that point (to check if it is within physical reach) and the exact angle the laser base
needs to rotate.

Your Task:

1. Include the <cmath> library at the top of your program.


2. Function Prototyping: At the very top of your file (before main), declare the prototypes
for two functions:
o float calculateDistance(float x, float y);
o float calculateAngle(float x, float y);
3. Write the main() function. Ask the user for targetX and targetY. Define a
constant MAX_REACH = 50.0; (cm).
4. Below your main() function, implement the two functions:

o calculateDistance must use the Pythagorean theorem: . Use


the sqrt() and pow() functions from <cmath>.
o calculateAngle must calculate the angle in Degrees. Use the atan2(y,
x) function, which returns radians. Convert it to degrees by multiplying
by (180.0 / 3.14159).
5. Inside main(), call the distance function. If the distance is strictly greater
than MAX_REACH, print "ERROR: Target Out of Bounds!".
6. If it is within reach, call the angle function and print: "Target Locked. Distance:
[dist] cm. Rotating to: [angle] degrees."

Engineering Trap: atan2() is extremely powerful in robotics because it handles all four
quadrants correctly, unlike standard atan(). If you use atan(y/x) instead of atan2(y, x),
your robot will aim backward when given negative X coordinates, causing severe hardware
collisions.
Question 6: FADEC Engine Controller - Architecture (Difficulty: Expert - Multi-Function
Interaction)

Scenario: You are acting as the Lead Systems Architect. You must design a simplified FADEC
(Full Authority Digital Engine Control) software loop for a jet engine. This requires
orchestrating multiple functions that pass data safely without relying on dangerous Global
Variables.

Your Task:

1. Create three separate functions:


o float readAirDensity(float altitude): If altitude is > 10000,
return 0.5 (thin air). Else, return 1.2 (dense air).
o float calculateFuelRate(float throttle, float airDensity): Formula
is throttle * airDensity.
o void injectFuel(float fuelRate, bool &engineOverheated): If fuelRate
> 80.0, print "CRITICAL: Engine Overheating!" and
set engineOverheated to true. Otherwise, print "Injecting [fuelRate] kg/s
of fuel."
2. In your main() function, declare bool isOverheated = false; and create
a while(!isOverheated) loop.
3. Inside the loop, ask the user for altitude and throttle (0-100).
4. The Pipeline: Call readAirDensity, pass its result into calculateFuelRate, and
pass that result into injectFuel.
5. When injectFuel changes isOverheated to true (via pass-by-reference),
the while loop must naturally terminate. Print "SYSTEM SHUTDOWN." after the loop.

The Architecture Test: This question tests your ability to route data cleanly. The output of Sensor
A goes into Math B, and the output of Math B goes into Actuator C. If you resort to declaring
global variables to move this data around, your code will be rejected.

Question 7: The IMU Sensor Calibration (Difficulty: Expert - Multiple Pass-by-Reference)

Scenario: You are programming the flight controller for a quadcopter. An Inertial Measurement
Unit (IMU) sensor provides Pitch, Roll, and Yaw angles. However, cheap sensors always have
an "offset" error when they boot up (e.g., they read 2.5 degrees when sitting perfectly flat). You
need a calibration function that reads the raw data, subtracts the known offsets, and gives the true
angles back to the main flight loop. Since you need to update 3 different variables at once, you
must use pass-by-reference.

Your Task:

1. Define a void function named calibrateIMU.


2. It must accept 6 parameters:
o float rawPitch, float rawRoll, float rawYaw (Inputs)
o float &truePitch, float &trueRoll, float &trueYaw (Outputs - passed by
reference)
3. Inside the function, calculate the true values by subtracting these hardware offsets:
o Pitch Offset: -2.5
o Roll Offset: 1.2
o Yaw Offset: 0.0 (Example: truePitch = rawPitch - (-2.5);)
4. In your main() function, declare three local variables for the true angles, initialized
to 0.0.
5. Ask the user to input the three raw angles.
6. Call the calibrateIMU function.
7. Print the updated true angles from inside main().

Engineering Trap: Notice that we didn't pass the offsets as parameters. Since the offsets are
physical constants tied to the specific hardware chip, they should be hardcoded inside
the calibrateIMU function or defined as global constants, keeping the function signature clean.

Question 8: The PWM Motor Driver Map

Scenario: You want to control the speed of a DC motor using Pulse Width Modulation (PWM).
The user wants to input the speed as a percentage (0 to 100), but the microcontroller's hardware
timer requires an 8-bit integer value (0 to 255). You need a "mapping" function to translate the
human percentage into a machine integer.

Your Task:

1. Define a function named mapPWM that returns an int and accepts one parameter: float
speedPercentage.
2. Inside the function, first ensure the percentage is safely clamped between 0 and 100. If
the user enters -50, force it to 0. If they enter 150, force it to 100.
3. Mathematically map the 0.0-100.0 range to the 0-
255 range. (Formula: (speedPercentage / 100.0) * 255.0)
4. Crucial: Since the hardware needs an integer, you must return the calculated value as
an int. Let the C++ compiler handle the truncation (dropping the decimals).
5. In your main() function, ask the user for a speed percentage.
6. Call mapPWM and print: "Writing PWM Value [result] to Motor Driver."

Question 9: The Peak Force Tracker

Scenario: You are writing software for an industrial load cell (a digital weight scale) used in
material stress testing. The machine pulls a piece of metal until it snaps. You need a function that
continuously receives the current force and "remembers" the absolute highest force it has ever
seen (Peak Force).

Your Task:
1. Define a function named updatePeakForce that returns a float and accepts one
parameter: float currentForce.
2. Inside the function, declare a static variable: static float peakForce = 0.0;
3. Compare currentForce to peakForce. If currentForce is higher, update peakForce.
4. return the peakForce.
5. In your main() function, create a while loop that asks the user to enter a force reading
(enter -1 to quit).
6. Inside the loop, call updatePeakForce and print: "New Reading: [current],
Historical Peak: [peak]"

The 'Static' Concept: A static local variable is a hybrid. Like a local variable, it is only visible
inside its specific function. But like a global variable, it remembers its value between function
calls instead of being destroyed and recreated every time. This is the safest way to give a
function "memory" without polluting the global scope.

Question 10: The Smart Thermostat Hysteresis

Scenario: You are writing a modular control function for a smart home heating system. The
target temperature is 22.0degrees. To prevent the heater from rapidly clicking on and off every
second (chattering), you must implement a "Deadband" (Hysteresis) of +/- 1.0 degree.

Your Task:

1. Define a global constant: const float TARGET_TEMP = 22.0;


2. Define a function named evaluateHeaterState that returns a bool (true for ON, false
for OFF).
3. It must accept two parameters: float currentTemp and bool previousHeaterState.
4. The Hysteresis Logic:
o If currentTemp is < 21.0 (Target - 1), return true (Turn Heater ON).
o If currentTemp is > 23.0 (Target + 1), return false (Turn Heater OFF).
o If the temperature is strictly between 21.0 and 23.0 (the deadband), the heater
should do nothing new. It must simply return its previousHeaterState.
5. In your main() function, declare bool isHeaterOn = false;.
6. Write a while loop that asks the user for the current temperature.
7. Call evaluateHeaterState, passing the current temperature and isHeaterOn.
8. Update isHeaterOn with the returned value, and print whether the heater is currently ON
or OFF.

Engineering Application: This teaches you how to pass the "historical state" of a system into a
function so it can make an intelligent, context-aware decision, rather than just a blind
mathematical comparison.

You might also like