From d18f12599541522f601f08d135eb2649dfe95b29 Mon Sep 17 00:00:00 2001 From: Alvie Rahman Date: Mon, 4 Dec 2023 17:56:13 +0000 Subject: [PATCH] first draft of submission --- csv/LeibRampStepper_out_50.csv | 51 +++++++++ csv/SimplisticRampStepper_out_50.csv | 51 +++++++++ src/submission.md | 149 ++++++++++++++++++++++++++- submission.mk | 2 +- 4 files changed, 248 insertions(+), 5 deletions(-) create mode 100644 csv/LeibRampStepper_out_50.csv create mode 100644 csv/SimplisticRampStepper_out_50.csv diff --git a/csv/LeibRampStepper_out_50.csv b/csv/LeibRampStepper_out_50.csv new file mode 100644 index 0000000..542ce39 --- /dev/null +++ b/csv/LeibRampStepper_out_50.csv @@ -0,0 +1,51 @@ + Time (s), Speed (steps/s), Accel (steps/s^2), Posit'n (steps), Step time (ticks) + 0.000, 4.583, 21.000, 1, 218.218 + 0.189, 5.304, 3.828, 2, 188.528 + 0.347, 6.359, 6.711, 3, 157.245 + 0.480, 7.531, 8.822, 4, 132.785 + 0.596, 8.653, 9.711, 5, 115.565 + 0.700, 9.688, 10.023, 6, 103.223 + 0.794, 10.640, 10.135, 7, 93.982 + 0.881, 11.523, 10.175, 8, 86.781 + 0.962, 12.348, 10.186, 9, 80.984 + 1.039, 13.124, 10.185, 10, 76.195 + 1.112, 13.859, 10.180, 11, 72.157 + 1.181, 14.558, 10.172, 12, 68.693 + 1.247, 15.225, 10.164, 13, 65.681 + 1.311, 15.865, 10.156, 14, 63.031 + 1.372, 16.481, 10.148, 15, 60.676 + 1.431, 17.075, 10.141, 16, 58.566 + 1.488, 17.649, 10.134, 17, 56.660 + 1.543, 18.205, 10.128, 18, 54.929 + 1.597, 18.745, 10.122, 19, 53.346 + 1.649, 19.270, 10.117, 20, 51.893 + 1.700, 19.782, 10.112, 21, 50.552 + 1.751, 19.782, 0.000, 22, 50.552 + 1.802, 19.782, 0.000, 23, 50.552 + 1.853, 19.782, 0.000, 24, 50.552 + 1.904, 19.782, 0.000, 25, 50.552 + 1.955, 19.782, 0.000, 26, 50.552 + 2.006, 19.782, 0.000, 27, 50.552 + 2.057, 19.782, 0.000, 28, 50.552 + 2.108, 19.782, 0.000, 29, 50.552 + 2.159, 19.782, 0.000, 30, 50.552 + 2.210, 19.782, 0.000, 31, 50.552 + 2.262, 19.270, -9.853, 32, 51.894 + 2.316, 18.745, -9.845, 33, 53.347 + 2.371, 18.205, -9.835, 34, 54.930 + 2.428, 17.648, -9.823, 35, 56.663 + 2.487, 17.074, -9.810, 36, 58.570 + 2.548, 16.479, -9.795, 37, 60.682 + 2.612, 15.863, -9.778, 38, 63.040 + 2.678, 15.222, -9.757, 39, 65.695 + 2.747, 14.553, -9.732, 40, 68.714 + 2.820, 13.853, -9.702, 41, 72.188 + 2.897, 13.116, -9.665, 42, 76.244 + 2.979, 12.336, -9.618, 43, 81.062 + 3.066, 11.506, -9.556, 44, 86.914 + 3.161, 10.613, -9.473, 45, 94.224 + 3.265, 9.643, -9.355, 46, 103.703 + 3.382, 8.572, -9.178, 47, 116.655 + 3.518, 7.365, -8.889, 48, 135.770 + 3.686, 5.962, -8.365, 49, 167.717 + 3.905, 4.583, -6.323, 50, 218.218 diff --git a/csv/SimplisticRampStepper_out_50.csv b/csv/SimplisticRampStepper_out_50.csv new file mode 100644 index 0000000..1f86694 --- /dev/null +++ b/csv/SimplisticRampStepper_out_50.csv @@ -0,0 +1,51 @@ + Time (s), Speed (steps/s), Accel (steps/s^2), Posit'n (steps), Step time (ticks) + 0.000, 1.000, 1.000, 1, 1000.000 + 0.953, 1.050, 0.052, 2, 952.500 + 1.858, 1.105, 0.061, 3, 905.000 + 2.716, 1.166, 0.071, 4, 857.500 + 3.526, 1.235, 0.084, 5, 810.000 + 4.289, 1.311, 0.101, 6, 762.500 + 5.004, 1.399, 0.122, 7, 715.000 + 5.672, 1.498, 0.149, 8, 667.500 + 6.292, 1.613, 0.185, 9, 620.000 + 6.865, 1.747, 0.234, 10, 572.500 + 7.390, 1.905, 0.301, 11, 525.000 + 7.868, 2.094, 0.397, 12, 477.500 + 8.298, 2.326, 0.538, 13, 430.000 + 8.681, 2.614, 0.755, 14, 382.500 + 9.016, 2.985, 1.107, 15, 335.000 + 9.304, 3.478, 1.715, 16, 287.500 + 9.544, 4.167, 2.868, 17, 240.000 + 9.737, 5.195, 5.341, 18, 192.500 + 9.882, 6.897, 11.736, 19, 145.000 + 9.980, 10.256, 34.460, 20, 97.500 + 10.030, 20.000, 194.872, 21, 50.000 + 10.080, 20.000, 0.000, 22, 50.000 + 10.130, 20.000, 0.000, 23, 50.000 + 10.180, 20.000, 0.000, 24, 50.000 + 10.230, 20.000, 0.000, 25, 50.000 + 10.280, 20.000, 0.000, 26, 50.000 + 10.330, 20.000, 0.000, 27, 50.000 + 10.380, 20.000, 0.000, 28, 50.000 + 10.430, 20.000, 0.000, 29, 50.000 + 10.480, 20.000, 0.000, 30, 50.000 + 10.578, 10.256, -99.934, 31, 97.500 + 10.723, 6.897, -23.171, 32, 145.000 + 10.916, 5.195, -8.840, 33, 192.500 + 11.156, 4.167, -4.284, 34, 240.000 + 11.444, 3.478, -2.394, 35, 287.500 + 11.779, 2.985, -1.472, 36, 335.000 + 12.162, 2.614, -0.969, 37, 382.500 + 12.592, 2.326, -0.672, 38, 430.000 + 13.070, 2.094, -0.484, 39, 477.500 + 13.595, 1.905, -0.361, 40, 525.000 + 14.168, 1.747, -0.276, 41, 572.500 + 14.788, 1.613, -0.216, 42, 620.000 + 15.456, 1.498, -0.172, 43, 667.500 + 16.171, 1.399, -0.139, 44, 715.000 + 16.934, 1.311, -0.114, 45, 762.500 + 17.744, 1.235, -0.095, 46, 810.000 + 18.602, 1.166, -0.080, 47, 857.500 + 19.507, 1.105, -0.068, 48, 905.000 + 20.460, 1.050, -0.058, 49, 952.500 + 21.460, 1.000, -0.050, 50, 1000.000 diff --git a/src/submission.md b/src/submission.md index 2228a1a..2c798d5 100755 --- a/src/submission.md +++ b/src/submission.md @@ -1,9 +1,8 @@ --- author: Akbar Rahman (20386125) date: \today -title: Change Me -tags: [ change_me ] -uuid: Change Me +title: MMME3085---Lab 2 Coursework +tags: [ mmme, mmme3086 ] documentclass: article geometry: - margin=1in @@ -15,4 +14,146 @@ geometry: \tableofcontents \newpage -# Header +# Question 1 + +As you increase the proportional gain, you increase the responsiveness of the motor to error, +but it is easy to go too high and cause the motor to oscillate around the target position. +This is because the motor current is set proportional to the error. +This means that if the motor is spinning too quickly, the proportional control will not slow +down the motor in time to avoid overshoot. +Additionally, if the target position is set too close to the motor, the proportional control +maybe not push enough current to motor to actually get it spinning in some cases. + +# Question 2 + +When derivative control is added at low levels (0.02) it reduces the oscillations. +This is because derivative control only considers the rate of change of of the error +and therefore tries to bring the rate of change to zero. + +# Question 3 + +There are two if statements in the loop function as the controller will work best and be able to respond +to changes faster if the control functions are run more frequently. +The faster the better. +However, the Arduino does not really need to print to serial every time as it is only used to ensure +the Arduino is running properly. + +If `prevMillisControl` and `prevMillisPrint` was replaced with just one variable, the `printLoop` function +would never run as the variable would have been updated to equal `currentMillis` before the print loop's +if statement will check its condition. + +# Question 4 + +First the library is `include`d on line 4: + +```c +#include +``` + +Then a PID object is created using the `myPID` function on line 48. +This object holds all the properties of the PID controller including values of $K_p$, $K_i$, and $K_d$, +as well as a pointers to variables with the current motor position, speed, and set point. + +```c +PID myPID(&encoderPosnMeasured, &percentSpeed, &positionSetPoint, Kp, Ki, Kd, DIRECT); +``` + +Some initialisation is run in `setup` on lines 89 and 90: + +```c + myPID.SetOutputLimits(-100,100); + myPID.SetMode(AUTOMATIC); +``` + +Then the main control loop starts. +The `loop` function runs the `controlLoop` function every 20 milliseconds (as defined by +`controlInterval`) on line 101. +The `controlLoop` function retrieves the current motor position and stores it in the variable +that the PID controller has a pointer to. +`myPID.Compute()` is then called to recompute the motor speed required to get to the set point +and this is stored in the `percentSpeed` variable as the controller has a pointer to it. +This new speed is passed to the `driveMotorPercent` function to update the motor's speed. + +# Question 5 + +The mathematically complex operations in `loop()` as it is run infrequently. +This is because it is inside an if statement with condition `convertNewNumber()`, which +returns `false` if there is no new data to convert (i.e. if there has not been any serial input +since the last loop). +Essentially, the complex operations only run once per serial input, meaning it is run very infrequently +compared to how many times the loop runs. + +# Question 6 + +Complex operations in `computeNewSpeed()` have been avoided because this function runs very frequently +(on the order of microseconds). +Therefore it is important that the function does not consume too many processor cycles, +else the Arduino will be able to do little else. + +# Question 7 + +If the stepper motor is run too quickly, steps will be skipped and it will not accelerate or +accelerate slowly. +It also makes a different noise to normal operation. + +This is because the pole pairs of the motor will be activated too soon if attempting to spin +the motor too fast. +If they are activated too soon, they will not have the desired effect of speeding up the rotation +of the shaft, as the magnets of the motor will not be aligned as needed. + +This is also why the steppers use a ramp function, so that the shaft has time accelerate to the +desired speed without skipping steps. + +# Question 8 + +```{ .matplotlib caption="A plot of velocity and acceleration for SimplisticRampStepper" dpi=150 } +import numpy as np +import matplotlib.pyplot as plt + +TIME = 'Time_s' +SPEED = 'Speed_stepss' +ACCEL = 'Accel_stepss2' +POS = 'Positn_steps' +STEP = 'Step_time_ticks' + +data = np.genfromtxt("csv/SimplisticRampStepper_out_50.csv", + delimiter=",", names=True, dtype=float) + +fig, ax1 = plt.subplots() +ax2 = ax1.twinx() + +ax1.plot(data[TIME], data[SPEED], label='Speed [steps/s]', color='tab:blue') +ax2.plot(data[TIME], data[ACCEL], label='Acceleration [steps/s^2]', color='tab:red') +ax1.set_ylabel('Speed [steps/s]') +ax2.set_ylabel('Acceleration [steps/s^2]') + +ax1.set_xlabel("Time [s]") + +fig.tight_layout() +``` + +```{ .matplotlib caption="A plot of velocity and acceleration for LeibRampStepper" dpi=150 } +import numpy as np +import matplotlib.pyplot as plt + +TIME = 'Time_s' +SPEED = 'Speed_stepss' +ACCEL = 'Accel_stepss2' +POS = 'Positn_steps' +STEP = 'Step_time_ticks' + +data = np.genfromtxt("csv/LeibRampStepper_out_50.csv", + delimiter=",", names=True, dtype=float) + +fig, ax1 = plt.subplots() +ax2 = ax1.twinx() + +ax1.plot(data[TIME], data[SPEED], label='Speed [steps/s]', color='tab:blue') +ax2.plot(data[TIME], data[ACCEL], label='Acceleration [steps/s^2]', color='tab:red') +ax1.set_ylabel('Speed [steps/s]') +ax2.set_ylabel('Acceleration [steps/s^2]') + +ax1.set_xlabel("Time [s]") + +fig.tight_layout() +``` diff --git a/submission.mk b/submission.mk index 9cc1fab..91ac23c 100644 --- a/submission.mk +++ b/submission.mk @@ -1 +1 @@ -SUBMISSION_FILENAME=changeme.pdf +SUBMISSION_FILENAME=mmme3086_lab2_coursework_akbar_alvi_rahman_20386125.pdf