From abc17980b5977c7d5fe03fdc841dca42df17dd6e Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Sat, 18 Nov 2023 13:39:39 -0700 Subject: [PATCH 01/14] Extrapolated basic motor information using bitwise operators --- .../Training/Core/Src/Training.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c index 43c85491..ba321916 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c @@ -1,9 +1,28 @@ #include "Training.h" +// uint8_t 8 bit-unsigned integer uint8_t outputArray[3]; uint8_t validData; // Set bits 0, 1, 2 if the input array elements were valid +/** +NOTE: I decided that if the motors do not have matching ON/OFF status or do not have matching velocity*, both motor inputs will be flagged as wrong (it's hard to know which motor is "right" when they are not in sync). + +* Velocity will be compared in its vector form. i.e. v1 = v2 if and only if they are equal in magnitude and direction. +*/ + + void trainingTask(uint8_t* data) { + // Check equality in motor ON/OFF status + // 00000001 (1) + uint8_t isMotorOneON = 1 & outputArray[0]; + uint8_t isMotorTwoON = 1 & outputArray[1]; + + // Check equality in motor velocity + // 01111110 (126) + uint8_t motorOneVelocity = 126 & outputArray[0]; + int motorTwoVelocity = 126 & outputArray[1]; + // Check motors are in sync + int isSynced = (isMotorOneON == isMotorTwoON) && (motorOneVelocity == motorTwoVelocity); } From 46b606007b1e0723f8db3424eedaaf68d96e3249 Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Sat, 18 Nov 2023 14:45:22 -0700 Subject: [PATCH 02/14] Finished implementing motor logic. Not tested. --- .../Training/Core/Src/Training.c | 51 ++++++++++++++++--- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c index ba321916..c364cddd 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c @@ -13,16 +13,51 @@ NOTE: I decided that if the motors do not have matching ON/OFF status or do not void trainingTask(uint8_t* data) { + // MOTORS // Check equality in motor ON/OFF status - // 00000001 (1) - uint8_t isMotorOneON = 1 & outputArray[0]; - uint8_t isMotorTwoON = 1 & outputArray[1]; + uint8_t isMotorOneOn = 0b00000001 & outputArray[0]; + uint8_t isMotorTwoOn = 0b00000001 & outputArray[1]; - // Check equality in motor velocity - // 01111110 (126) - uint8_t motorOneVelocity = 126 & outputArray[0]; - int motorTwoVelocity = 126 & outputArray[1]; + // Check equality in velocity (magnitude and direction) + uint8_t motorOneVelocity = (0b01111110 & outputArray[0]) >> 1; + uint8_t motorTwoVelocity = (0b01111110 & outputArray[1]) >> 1; // Check motors are in sync - int isSynced = (isMotorOneON == isMotorTwoON) && (motorOneVelocity == motorTwoVelocity); + int isSynced = (isMotorOneOn == isMotorTwoOn) && (motorOneVelocity == motorTwoVelocity); + + if (isSynced) + { + // Set Motor 1 + checkMotorData(isMotorOneOn, motorOneVelocity) ? validData[0] = 1 : validData[0] = 0; + // Set Motor 2 + checkMotorData(isMotorTwoOn, motorTwoVelocity) ? validData[1] = 1 : validData[1] = 0; + } else + { + validData[0] = 0; + validData[1] = 0; + } + + // LIGHTS + + +} + +/** @brief Function that takes in motor ON/OFF status and returns 1 if data +* is valid and 0 if data is not valid. This function only looks at the motor as a +* standalone unit and aasumes that it is synced with the other motor. +* +* @param[in] isMotorOn 8 bit integer with value 0000000 or 0000001 +* @param[in] motorVelocity 8 bit integer representing the velocity of the motor +*/ +int checkMotorData(uint8_t isMotorOn, uint8_t motorVelocity) { + // When motor is off we need to check velocity + if (!isMotorOn) + { + // Since motor is off, input is valid iff velocity is 0 + !velocity? return 1: return 0; + } + + // Since we are assuming that motors are synced, any on state is valid + return 1; + } From 6968f67ed670c47dfb56eae66306c2187428f2f2 Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Mon, 20 Nov 2023 14:32:03 -0700 Subject: [PATCH 03/14] Finished implementing lights logic. Not tested --- .../Training/Core/Src/Training.c | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c index c364cddd..597621b5 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c @@ -10,7 +10,6 @@ NOTE: I decided that if the motors do not have matching ON/OFF status or do not * Velocity will be compared in its vector form. i.e. v1 = v2 if and only if they are equal in magnitude and direction. */ - void trainingTask(uint8_t* data) { // MOTORS @@ -28,9 +27,9 @@ void trainingTask(uint8_t* data) if (isSynced) { // Set Motor 1 - checkMotorData(isMotorOneOn, motorOneVelocity) ? validData[0] = 1 : validData[0] = 0; + isMotorDataValid(isMotorOneOn, motorOneVelocity) ? validData[0] = 1 : validData[0] = 0; // Set Motor 2 - checkMotorData(isMotorTwoOn, motorTwoVelocity) ? validData[1] = 1 : validData[1] = 0; + isMotorDataValid(isMotorTwoOn, motorTwoVelocity) ? validData[1] = 1 : validData[1] = 0; } else { validData[0] = 0; @@ -38,6 +37,25 @@ void trainingTask(uint8_t* data) } // LIGHTS + // Check exactly one of the headlight statuses is on + uint8_t isHeadlightOff = (0b10000000 & lightData) >> 7; + uint8_t isHeadlightLow = (0b01000000 & lightData) >> 6; + uint8_t isHeadlightHigh = (0b00100000 & lightData) >> 5; + uint8_t isHeadlightValid = isHeadlightOff ^ isHeadlightLow ^ isHeadlightHigh; + + // In order to check signal lights we needs to know if hazards are on and then determine the right behaviour + uint8_t isHazardOn = (0b00000100 & lightData) >> 2; + uint8_t isRightSignalOn = (0b00010000 & lightData) >> 4; + uint8_t isLeftSignalOn = (0b00001000 & lightData) >> 3; + uint8_t isSignalValid; + if (isHazardOn) + { + // When hazard light is on, the signals must both be in the same state to denote blinking. + isSignalValid = !(isRightSignalOn ^ isLeftSignalOn); + } else { + // Signals may not be on at the same time + isSignalValid = !(isRightSignalOn && isLeftSignalOn); + } } @@ -49,7 +67,7 @@ void trainingTask(uint8_t* data) * @param[in] isMotorOn 8 bit integer with value 0000000 or 0000001 * @param[in] motorVelocity 8 bit integer representing the velocity of the motor */ -int checkMotorData(uint8_t isMotorOn, uint8_t motorVelocity) { +int isMotorDataValid(uint8_t isMotorOn, uint8_t motorVelocity) { // When motor is off we need to check velocity if (!isMotorOn) { From fbeb8eda524a1e5fcfd47571aa8ad4601a8c4af6 Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Mon, 20 Nov 2023 15:23:39 -0700 Subject: [PATCH 04/14] Fixed naming misunderstanding of array names. --- .../Training/Core/Src/Training.c | 31 +++++++++++++------ .../Training/Test/TrainingTest.c | 5 ++- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c index 597621b5..24e50d34 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c @@ -14,12 +14,12 @@ void trainingTask(uint8_t* data) { // MOTORS // Check equality in motor ON/OFF status - uint8_t isMotorOneOn = 0b00000001 & outputArray[0]; - uint8_t isMotorTwoOn = 0b00000001 & outputArray[1]; + uint8_t isMotorOneOn = 0b00000001 & data[0]; + uint8_t isMotorTwoOn = 0b00000001 & data[1]; // Check equality in velocity (magnitude and direction) - uint8_t motorOneVelocity = (0b01111110 & outputArray[0]) >> 1; - uint8_t motorTwoVelocity = (0b01111110 & outputArray[1]) >> 1; + uint8_t motorOneVelocity = (0b01111110 & data[0]) >> 1; + uint8_t motorTwoVelocity = (0b01111110 & data[1]) >> 1; // Check motors are in sync int isSynced = (isMotorOneOn == isMotorTwoOn) && (motorOneVelocity == motorTwoVelocity); @@ -38,16 +38,17 @@ void trainingTask(uint8_t* data) // LIGHTS // Check exactly one of the headlight statuses is on - uint8_t isHeadlightOff = (0b10000000 & lightData) >> 7; - uint8_t isHeadlightLow = (0b01000000 & lightData) >> 6; - uint8_t isHeadlightHigh = (0b00100000 & lightData) >> 5; + uint8_t isHeadlightOff = (0b10000000 & data[2]) >> 7; + uint8_t isHeadlightLow = (0b01000000 & data[2]) >> 6; + uint8_t isHeadlightHigh = (0b00100000 & data[2]) >> 5; uint8_t isHeadlightValid = isHeadlightOff ^ isHeadlightLow ^ isHeadlightHigh; // In order to check signal lights we needs to know if hazards are on and then determine the right behaviour - uint8_t isHazardOn = (0b00000100 & lightData) >> 2; - uint8_t isRightSignalOn = (0b00010000 & lightData) >> 4; - uint8_t isLeftSignalOn = (0b00001000 & lightData) >> 3; + uint8_t isHazardOn = (0b00000100 & data[2]) >> 2; + uint8_t isRightSignalOn = (0b00010000 & data[2]) >> 4; + uint8_t isLeftSignalOn = (0b00001000 & data[2]) >> 3; uint8_t isSignalValid; + if (isHazardOn) { // When hazard light is on, the signals must both be in the same state to denote blinking. @@ -57,6 +58,16 @@ void trainingTask(uint8_t* data) isSignalValid = !(isRightSignalOn && isLeftSignalOn); } + isHeadlightValid && isSignalValid ? validData[2] = 1 : validData[2] = 0; + + // Write to outpuData iff data is valid + if (validData[0] == 0 && validData[1] == 0 && validData[2] == 0) + { + for (int i = 0; i < 3; i++) + { + outputArray[i] = data[i]; + } + } } diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c index 959a9e69..dccb2bad 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c @@ -7,7 +7,10 @@ extern uint8_t validData; void runTrainingTests() { - // Run all the tests here using RUN_TEST() + RUN_TEST(test_EverythingValid); + RUN_TEST(test_EverythingInvalid); + RUN_TEST(test_OnlyLightsInvalid); + RUN_TEST(test_OnlyMotorsInvalid); } void test_EverythingValid() From 6f9ffad893fe23db4c47978e0d01faa996de4eb1 Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Mon, 20 Nov 2023 18:19:39 -0700 Subject: [PATCH 05/14] Fixed mistake and implemented validData as an int rather than an array. --- .../Training/Core/Src/Training.c | 29 +++++-------------- .../Training/Test/TrainingTest.c | 16 +++++++--- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c index 24e50d34..cdc7d6b1 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c @@ -24,17 +24,8 @@ void trainingTask(uint8_t* data) // Check motors are in sync int isSynced = (isMotorOneOn == isMotorTwoOn) && (motorOneVelocity == motorTwoVelocity); - if (isSynced) - { - // Set Motor 1 - isMotorDataValid(isMotorOneOn, motorOneVelocity) ? validData[0] = 1 : validData[0] = 0; - // Set Motor 2 - isMotorDataValid(isMotorTwoOn, motorTwoVelocity) ? validData[1] = 1 : validData[1] = 0; - } else - { - validData[0] = 0; - validData[1] = 0; - } + // If the motors are in sync only need to check if one motor is valid since they must be equal! + isSynced && isMotorDataValid(isMotorOneOn, motorOneVelocity) ? validData = 0b11000000 : validData = 0b00000000; // LIGHTS // Check exactly one of the headlight statuses is on @@ -49,19 +40,15 @@ void trainingTask(uint8_t* data) uint8_t isLeftSignalOn = (0b00001000 & data[2]) >> 3; uint8_t isSignalValid; - if (isHazardOn) - { - // When hazard light is on, the signals must both be in the same state to denote blinking. - isSignalValid = !(isRightSignalOn ^ isLeftSignalOn); - } else { - // Signals may not be on at the same time - isSignalValid = !(isRightSignalOn && isLeftSignalOn); - } + // When hazard light is on, the signals must both be in the same state to denote blinking. + // When hazards are not on, signals may not be on at the same time + isHazardOn ? isSignalValid = !(isRightSignalOn ^ isLeftSignalOn) : isSignalValid = !(isRightSignalOn && isLeftSignalOn); - isHeadlightValid && isSignalValid ? validData[2] = 1 : validData[2] = 0; + // Set bit 2 of validData accordingly + isHeadlightValid && isSignalValid ? validData = 0b00100000 | validData : validData = 0b11011111 & validData; // Write to outpuData iff data is valid - if (validData[0] == 0 && validData[1] == 0 && validData[2] == 0) + if (validData == 0b11100000) { for (int i = 0; i < 3; i++) { diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c index dccb2bad..b5e79de8 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c @@ -7,15 +7,15 @@ extern uint8_t validData; void runTrainingTests() { - RUN_TEST(test_EverythingValid); - RUN_TEST(test_EverythingInvalid); - RUN_TEST(test_OnlyLightsInvalid); + // RUN_TEST(test_EverythingValid); + // RUN_TEST(test_EverythingInvalid); + // RUN_TEST(test_OnlyLightsInvalid); RUN_TEST(test_OnlyMotorsInvalid); } void test_EverythingValid() { - + } void test_EverythingInvalid() @@ -30,5 +30,13 @@ void test_OnlyLightsInvalid() void test_OnlyMotorsInvalid() { + // Case 1: Motors not in sync + uint8_t data1[3] = {0b11100111, 0b01001001, 0b01000000}; + uint8_t expected[3] = {0,0,1}; + TEST_ASSERT_EACH_EQUAL_UINT8(expected, trainingTask(data1)); + + // Case 2: Motors in sync, but turned off with non-zero velocity + uint8_t data2[3] = {0b11000000, 0b11000000, 0b01000000}; + TEST_ASSERT_EACH_EQUAL_UINT8(expected, trainingTask(data2)); } From 98a3e7d1bafcc410981ec93adacb03862adf15b3 Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Mon, 20 Nov 2023 18:54:46 -0700 Subject: [PATCH 06/14] Added test data for each test. Need to actually implement the tests. --- .../Embedded-Teaser/Training/Core/Src/Training.c | 4 ++++ .../Embedded-Teaser/Training/Test/TrainingTest.c | 15 ++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c index cdc7d6b1..b50d283d 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c @@ -66,6 +66,10 @@ void trainingTask(uint8_t* data) * @param[in] motorVelocity 8 bit integer representing the velocity of the motor */ int isMotorDataValid(uint8_t isMotorOn, uint8_t motorVelocity) { + + // TODO: If motor is moving forward, then the sign of the bit should be positive. + + // When motor is off we need to check velocity if (!isMotorOn) { diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c index b5e79de8..4f9a763f 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c @@ -15,16 +15,25 @@ void runTrainingTests() void test_EverythingValid() { - + uint8_t data[3] = {0b1001001,0b1001001, 0011000}; } void test_EverythingInvalid() { + uint8_t data[3] = {0b11011011, 0b10010000, 0b11111000}; } void test_OnlyLightsInvalid() { + // Case 1: Headlights are in two states + uint8_t data1[3] = {0b10010111,0b10010111,0b11000000}; + + // Case 2: Hazards off, but both signals are on + uint8_t data2[3] = {0b10010111,0b10010111,0b10011000}; + + // Case 3: Hazards on, but signals not flashing + uint8_t data3[3] = {0b10010111,0b10010111,0b10010100}; } @@ -32,11 +41,7 @@ void test_OnlyMotorsInvalid() { // Case 1: Motors not in sync uint8_t data1[3] = {0b11100111, 0b01001001, 0b01000000}; - uint8_t expected[3] = {0,0,1}; - TEST_ASSERT_EACH_EQUAL_UINT8(expected, trainingTask(data1)); - // Case 2: Motors in sync, but turned off with non-zero velocity uint8_t data2[3] = {0b11000000, 0b11000000, 0b01000000}; - TEST_ASSERT_EACH_EQUAL_UINT8(expected, trainingTask(data2)); } From 58f3bf5a9cb09856016c38f18f79cd401854b95c Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Mon, 20 Nov 2023 19:16:31 -0700 Subject: [PATCH 07/14] Flagged motor validation mistake that needs to be fixed. --- .../Embedded-Teaser/Training/Core/Src/Training.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c index b50d283d..9bf39e95 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c @@ -54,7 +54,7 @@ void trainingTask(uint8_t* data) { outputArray[i] = data[i]; } - } + }; } From 3a33478bca9f1b2ca7d343fd207980398fac54b2 Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Sat, 25 Nov 2023 14:25:01 -0700 Subject: [PATCH 08/14] Fixed ternary operator mistakes --- .../Training/Core/Src/Training.c | 34 ++++++++++--------- .../Training/Test/TrainingTest.c | 2 +- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c index 9bf39e95..f983c8e5 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c @@ -3,6 +3,7 @@ // uint8_t 8 bit-unsigned integer uint8_t outputArray[3]; uint8_t validData; // Set bits 0, 1, 2 if the input array elements were valid +uint8_t isMotorDataValid(uint8_t isMotorOn, uint8_t motorVelocity); /** NOTE: I decided that if the motors do not have matching ON/OFF status or do not have matching velocity*, both motor inputs will be flagged as wrong (it's hard to know which motor is "right" when they are not in sync). @@ -18,14 +19,14 @@ void trainingTask(uint8_t* data) uint8_t isMotorTwoOn = 0b00000001 & data[1]; // Check equality in velocity (magnitude and direction) - uint8_t motorOneVelocity = (0b01111110 & data[0]) >> 1; - uint8_t motorTwoVelocity = (0b01111110 & data[1]) >> 1; + uint8_t motorOneVelocity = (0b11111110 & data[0]) >> 1; + uint8_t motorTwoVelocity = (0b11111110 & data[1]) >> 1; // Check motors are in sync - int isSynced = (isMotorOneOn == isMotorTwoOn) && (motorOneVelocity == motorTwoVelocity); + uint8_t isSynced = (isMotorOneOn == isMotorTwoOn) && (motorOneVelocity == motorTwoVelocity); // If the motors are in sync only need to check if one motor is valid since they must be equal! - isSynced && isMotorDataValid(isMotorOneOn, motorOneVelocity) ? validData = 0b11000000 : validData = 0b00000000; + validData = isSynced && isMotorDataValid(isMotorOneOn, motorOneVelocity) ? 0b11000000 : 0b00000000; // LIGHTS // Check exactly one of the headlight statuses is on @@ -42,10 +43,10 @@ void trainingTask(uint8_t* data) // When hazard light is on, the signals must both be in the same state to denote blinking. // When hazards are not on, signals may not be on at the same time - isHazardOn ? isSignalValid = !(isRightSignalOn ^ isLeftSignalOn) : isSignalValid = !(isRightSignalOn && isLeftSignalOn); + isSignalValid = isHazardOn ? !(isRightSignalOn ^ isLeftSignalOn) : !(isRightSignalOn && isLeftSignalOn); // Set bit 2 of validData accordingly - isHeadlightValid && isSignalValid ? validData = 0b00100000 | validData : validData = 0b11011111 & validData; + validData = isHeadlightValid && isSignalValid ? 0b00100000 | validData : 0b11011111 & validData; // Write to outpuData iff data is valid if (validData == 0b11100000) @@ -63,21 +64,22 @@ void trainingTask(uint8_t* data) * standalone unit and aasumes that it is synced with the other motor. * * @param[in] isMotorOn 8 bit integer with value 0000000 or 0000001 -* @param[in] motorVelocity 8 bit integer representing the velocity of the motor +* @param[in] motorVelocity 8 bit integer representing the velocity of the motor. */ -int isMotorDataValid(uint8_t isMotorOn, uint8_t motorVelocity) { - - // TODO: If motor is moving forward, then the sign of the bit should be positive. - +uint8_t isMotorDataValid(uint8_t isMotorOn, uint8_t motorVelocity) { // When motor is off we need to check velocity if (!isMotorOn) - { + { // Since motor is off, input is valid iff velocity is 0 - !velocity? return 1: return 0; + return (!motorVelocity) ? 1 : 0; + } else + { + // If motor is on, the sign of the velocity needs to match the direction + // Forward: 1, Positive: 0 + uint8_t isForward = (0b01000000 & motorVelocity) >> 6; + uint8_t velocitySign = (0b00000001 & motorOneVelocity); + return (isForward == ~velocitySign) ? 1 : 0; } - - // Since we are assuming that motors are synced, any on state is valid - return 1; } diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c index 4f9a763f..f44b784d 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c @@ -15,7 +15,7 @@ void runTrainingTests() void test_EverythingValid() { - uint8_t data[3] = {0b1001001,0b1001001, 0011000}; + uint8_t data[3] = {0b1001001,0b1001001, 0b011000}; } void test_EverythingInvalid() From f576fea5fed7b0fe79bef164dfd4b5bc39f716f1 Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Mon, 27 Nov 2023 18:16:06 -0700 Subject: [PATCH 09/14] Fixed everything valid test bugs --- .../Training/Core/Src/Training.c | 17 +++++++-------- .../Training/Test/TrainingTest.c | 21 ++++++++++++++++--- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c index f983c8e5..a147b6b8 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c @@ -68,18 +68,15 @@ void trainingTask(uint8_t* data) */ uint8_t isMotorDataValid(uint8_t isMotorOn, uint8_t motorVelocity) { - // When motor is off we need to check velocity - if (!isMotorOn) - { - // Since motor is off, input is valid iff velocity is 0 - return (!motorVelocity) ? 1 : 0; - } else - { + if(isMotorOn){ // If motor is on, the sign of the velocity needs to match the direction // Forward: 1, Positive: 0 - uint8_t isForward = (0b01000000 & motorVelocity) >> 6; - uint8_t velocitySign = (0b00000001 & motorOneVelocity); - return (isForward == ~velocitySign) ? 1 : 0; + uint8_t isForward = (0b10000000 & motorVelocity) >> 6; + uint8_t velocitySign = (0b00000001 & motorVelocity); + return (isForward != velocitySign) ? 1 : 0; + } else { + // Since motor is off, input is valid iff velocity is 0 + return (!motorVelocity) ? 1 : 0; } } diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c index f44b784d..5adba5db 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c @@ -4,23 +4,30 @@ extern uint8_t outputArray[3]; extern uint8_t validData; +void resetOutput(); void runTrainingTests() { - // RUN_TEST(test_EverythingValid); + RUN_TEST(test_EverythingValid); // RUN_TEST(test_EverythingInvalid); // RUN_TEST(test_OnlyLightsInvalid); - RUN_TEST(test_OnlyMotorsInvalid); + // RUN_TEST(test_OnlyMotorsInvalid); } void test_EverythingValid() { - uint8_t data[3] = {0b1001001,0b1001001, 0b011000}; + resetOutput(); + uint8_t data[3] = {0b01001011,0b01001011, 0b00110000}; + trainingTask(data); + TEST_ASSERT_EQUAL_UINT8(0b11100000, validData); } void test_EverythingInvalid() { + // resetOutput(); uint8_t data[3] = {0b11011011, 0b10010000, 0b11111000}; + // trainingTask(data); + } @@ -45,3 +52,11 @@ void test_OnlyMotorsInvalid() // Case 2: Motors in sync, but turned off with non-zero velocity uint8_t data2[3] = {0b11000000, 0b11000000, 0b01000000}; } + +void resetOutput() { + for (int i = 0; i < 3; i++) + { + outputArray[i] = 0; + } + validData = 0; +} From 88e41e08ce078a43da8cb714720a01251c69cbfa Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Mon, 27 Nov 2023 18:45:38 -0700 Subject: [PATCH 10/14] Everything invalid test passed --- .../Embedded-Teaser/Training/Test/TrainingTest.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c index 5adba5db..01190e0b 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c @@ -9,7 +9,7 @@ void resetOutput(); void runTrainingTests() { RUN_TEST(test_EverythingValid); - // RUN_TEST(test_EverythingInvalid); + RUN_TEST(test_EverythingInvalid); // RUN_TEST(test_OnlyLightsInvalid); // RUN_TEST(test_OnlyMotorsInvalid); } @@ -18,24 +18,30 @@ void test_EverythingValid() { resetOutput(); uint8_t data[3] = {0b01001011,0b01001011, 0b00110000}; + uint8_t expected[3] = {0b01001011,0b01001011, 0b00110000}; trainingTask(data); TEST_ASSERT_EQUAL_UINT8(0b11100000, validData); + TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, outputArray, 3); } void test_EverythingInvalid() { - // resetOutput(); + resetOutput(); uint8_t data[3] = {0b11011011, 0b10010000, 0b11111000}; - // trainingTask(data); - - + uint8_t expected[3] = {0,0,0}; + trainingTask(data); + TEST_ASSERT_EQUAL_UINT8(0b00000000, validData); + TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, outputArray, 3); } void test_OnlyLightsInvalid() { // Case 1: Headlights are in two states + // resetOutput(); uint8_t data1[3] = {0b10010111,0b10010111,0b11000000}; + // TEST_ASSERT_EQUAL_UINT8(0b00000000, validData); + // Case 2: Hazards off, but both signals are on uint8_t data2[3] = {0b10010111,0b10010111,0b10011000}; From 350521738639c02897b26ed2789cc8e3487bf42f Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Mon, 27 Nov 2023 18:52:00 -0700 Subject: [PATCH 11/14] Refactored code to writte to outputArray only data that is correct --- .../Training/Core/Src/Training.c | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c index a147b6b8..813db4ca 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c @@ -26,7 +26,17 @@ void trainingTask(uint8_t* data) uint8_t isSynced = (isMotorOneOn == isMotorTwoOn) && (motorOneVelocity == motorTwoVelocity); // If the motors are in sync only need to check if one motor is valid since they must be equal! - validData = isSynced && isMotorDataValid(isMotorOneOn, motorOneVelocity) ? 0b11000000 : 0b00000000; + // Set validData bits accordingly + // If motors are valid, copy data onto outputArray + if(isSynced && isMotorDataValid(isMotorOneOn, motorOneVelocity)){ + validData = 0b11000000; + outputArray[0] = data[0]; + outputArray[1] = data[1]; + } else { + validData = 0b00000000; + } + + //validData = isSynced && isMotorDataValid(isMotorOneOn, motorOneVelocity) ? 0b11000000 : 0b00000000; // LIGHTS // Check exactly one of the headlight statuses is on @@ -45,17 +55,25 @@ void trainingTask(uint8_t* data) // When hazards are not on, signals may not be on at the same time isSignalValid = isHazardOn ? !(isRightSignalOn ^ isLeftSignalOn) : !(isRightSignalOn && isLeftSignalOn); + // Copy data onto outputArray if lights are valid // Set bit 2 of validData accordingly - validData = isHeadlightValid && isSignalValid ? 0b00100000 | validData : 0b11011111 & validData; + if (isHeadlightValid && isSignalValid) + { + validData = 0b00100000 | validData; + outputArray[2] = data[2]; + } else { + validData = 0b11011111 & validData; + } + // validData = isHeadlightValid && isSignalValid ? 0b00100000 | validData : 0b11011111 & validData; // Write to outpuData iff data is valid - if (validData == 0b11100000) - { - for (int i = 0; i < 3; i++) - { - outputArray[i] = data[i]; - } - }; + // if (validData == 0b11100000) + // { + // for (int i = 0; i < 3; i++) + // { + // outputArray[i] = data[i]; + // } + // }; } From 0128f3516f3e241d9523d6ea12c9bd4fbbffda61 Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Mon, 27 Nov 2023 18:57:48 -0700 Subject: [PATCH 12/14] Only lights invalid test passing --- .../Training/Test/TrainingTest.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c index 01190e0b..b5607bdd 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c @@ -10,7 +10,7 @@ void runTrainingTests() { RUN_TEST(test_EverythingValid); RUN_TEST(test_EverythingInvalid); - // RUN_TEST(test_OnlyLightsInvalid); + RUN_TEST(test_OnlyLightsInvalid); // RUN_TEST(test_OnlyMotorsInvalid); } @@ -36,17 +36,26 @@ void test_EverythingInvalid() void test_OnlyLightsInvalid() { + uint8_t expected[3] = {0b10010111,0b10010111,0}; + // Case 1: Headlights are in two states - // resetOutput(); + resetOutput(); uint8_t data1[3] = {0b10010111,0b10010111,0b11000000}; - - // TEST_ASSERT_EQUAL_UINT8(0b00000000, validData); + trainingTask(data1); + TEST_ASSERT_EQUAL_UINT8(0b11000000, validData); + TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, outputArray, 3); // Case 2: Hazards off, but both signals are on uint8_t data2[3] = {0b10010111,0b10010111,0b10011000}; + trainingTask(data2); + TEST_ASSERT_EQUAL_UINT8(0b11000000, validData); + TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, outputArray, 3); // Case 3: Hazards on, but signals not flashing uint8_t data3[3] = {0b10010111,0b10010111,0b10010100}; + trainingTask(data3); + TEST_ASSERT_EQUAL_UINT8(0b11000000, validData); + TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, outputArray, 3); } From e5713a95176f954a0f9a1e69d27135e8b81354d5 Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Mon, 27 Nov 2023 19:04:39 -0700 Subject: [PATCH 13/14] All the tests passed yayyyyyyyyyy --- .../Embedded-Teaser/Training/Test/TrainingTest.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c index b5607bdd..aa648fdd 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Test/TrainingTest.c @@ -11,7 +11,7 @@ void runTrainingTests() RUN_TEST(test_EverythingValid); RUN_TEST(test_EverythingInvalid); RUN_TEST(test_OnlyLightsInvalid); - // RUN_TEST(test_OnlyMotorsInvalid); + RUN_TEST(test_OnlyMotorsInvalid); } void test_EverythingValid() @@ -46,12 +46,14 @@ void test_OnlyLightsInvalid() TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, outputArray, 3); // Case 2: Hazards off, but both signals are on + resetOutput(); uint8_t data2[3] = {0b10010111,0b10010111,0b10011000}; trainingTask(data2); TEST_ASSERT_EQUAL_UINT8(0b11000000, validData); TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, outputArray, 3); // Case 3: Hazards on, but signals not flashing + resetOutput(); uint8_t data3[3] = {0b10010111,0b10010111,0b10010100}; trainingTask(data3); TEST_ASSERT_EQUAL_UINT8(0b11000000, validData); @@ -61,11 +63,20 @@ void test_OnlyLightsInvalid() void test_OnlyMotorsInvalid() { + uint8_t expected[3] = {0,0,0b01000000}; // Case 1: Motors not in sync + resetOutput(); uint8_t data1[3] = {0b11100111, 0b01001001, 0b01000000}; + trainingTask(data1); + TEST_ASSERT_EQUAL_UINT8(0b00100000, validData); + TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, outputArray, 3); // Case 2: Motors in sync, but turned off with non-zero velocity + resetOutput(); uint8_t data2[3] = {0b11000000, 0b11000000, 0b01000000}; + trainingTask(data2); + TEST_ASSERT_EQUAL_UINT8(0b00100000, validData); + TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, outputArray, 3); } void resetOutput() { From 5ef4fa9ed92903c81b2bfaae943eec803d9d6cea Mon Sep 17 00:00:00 2001 From: Paula Amaya Date: Mon, 27 Nov 2023 19:07:20 -0700 Subject: [PATCH 14/14] Cleaned messy comments that kept me sane throughout this exercise --- .../Embedded-Teaser/Training/Core/Src/Training.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c index 813db4ca..1b4eb831 100644 --- a/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c +++ b/Recruit-Training/Advanced-Recruit-Training/Embedded-Teaser/Training/Core/Src/Training.c @@ -10,7 +10,6 @@ NOTE: I decided that if the motors do not have matching ON/OFF status or do not * Velocity will be compared in its vector form. i.e. v1 = v2 if and only if they are equal in magnitude and direction. */ - void trainingTask(uint8_t* data) { // MOTORS @@ -36,8 +35,6 @@ void trainingTask(uint8_t* data) validData = 0b00000000; } - //validData = isSynced && isMotorDataValid(isMotorOneOn, motorOneVelocity) ? 0b11000000 : 0b00000000; - // LIGHTS // Check exactly one of the headlight statuses is on uint8_t isHeadlightOff = (0b10000000 & data[2]) >> 7; @@ -45,7 +42,7 @@ void trainingTask(uint8_t* data) uint8_t isHeadlightHigh = (0b00100000 & data[2]) >> 5; uint8_t isHeadlightValid = isHeadlightOff ^ isHeadlightLow ^ isHeadlightHigh; - // In order to check signal lights we needs to know if hazards are on and then determine the right behaviour + // In order to check signal lights we needs to know if hazards are on and then determine the right behaviour. uint8_t isHazardOn = (0b00000100 & data[2]) >> 2; uint8_t isRightSignalOn = (0b00010000 & data[2]) >> 4; uint8_t isLeftSignalOn = (0b00001000 & data[2]) >> 3; @@ -64,16 +61,6 @@ void trainingTask(uint8_t* data) } else { validData = 0b11011111 & validData; } - // validData = isHeadlightValid && isSignalValid ? 0b00100000 | validData : 0b11011111 & validData; - - // Write to outpuData iff data is valid - // if (validData == 0b11100000) - // { - // for (int i = 0; i < 3; i++) - // { - // outputArray[i] = data[i]; - // } - // }; }