commit aed668f7211f621ef051974804213aeadb212c47 Author: ZeroZipp Date: Mon Jan 12 10:10:45 2026 +0100 first commit diff --git a/include/motor.hpp b/include/motor.hpp new file mode 100644 index 0000000..0ada863 --- /dev/null +++ b/include/motor.hpp @@ -0,0 +1,64 @@ +#pragma once +#include + +class Motor { + private: GPIO_TypeDef* gpio; + private: int pinMask, lastStepTime; + private: int sequence[4], currentStep; + private: int maxSteps, stepCount; + + public: Motor(GPIO_TypeDef* gpio, + int pinOffset, int maxSteps) { + /* Initialize sequence and mask */ + sequence[0] = 0x0003 << pinOffset; + sequence[1] = 0x0006 << pinOffset; + sequence[2] = 0x000C << pinOffset; + sequence[3] = 0x0009 << pinOffset; + pinMask = 0x000F << pinOffset; + + /* Set initial values */ + lastStepTime = millis(); + this -> maxSteps = maxSteps; + this -> gpio = gpio; + currentStep = 0; + stepCount = 0; + } + + public: void begin() { + /* A bad solution to a non-existing problem */ + if(gpio == GPIOA) RCC->AHBENR |= RCC_AHBENR_GPIOAEN; + else if(gpio == GPIOB) RCC->AHBENR |= RCC_AHBENR_GPIOBEN; + else if(gpio == GPIOC) RCC->AHBENR |= RCC_AHBENR_GPIOCEN; + else if(gpio == GPIOD) RCC->AHBENR |= RCC_AHBENR_GPIODEN; + else if(gpio == GPIOF) RCC->AHBENR |= RCC_AHBENR_GPIOFEN; + + /* Set initial values */ + lastStepTime = millis(); + gpio -> MODER = 0x5555555; + gpio -> ODR = 0; + currentStep = 0; + stepCount = 0; + } + + private: void step(bool clockwise, int delay) { + /* Progress sequence and thus turn motor */ + if(millis() - lastStepTime < delay) return; + int next = (currentStep + 1) % 4, back = (currentStep + 3) % 4; + gpio -> ODR = (gpio -> ODR & ~pinMask) | sequence[currentStep]; + currentStep = clockwise ? next : back; + stepCount += clockwise ? 1 : -1; + lastStepTime = millis(); + } + + public: int angle() { + /* Calculate rotation angle */ + float count = (float) stepCount; + return (count / maxSteps) * 360; + } + + public: void update(int target, int delay) { + /* Rotate motor towards given angle */ + if(angle() == target) return; + step(angle() < target, delay); + } +}; \ No newline at end of file diff --git a/include/robot.hpp b/include/robot.hpp new file mode 100644 index 0000000..6c84592 --- /dev/null +++ b/include/robot.hpp @@ -0,0 +1,52 @@ +#pragma once +#include "motor.hpp" +#include + +class Robot { + private: float size; + private: Motor arm1; + private: Motor arm2; + private: Motor yaw; + + public: Robot(float size, + const Motor& yaw, const Motor& arm1, const Motor& arm2 + ) : size(size), arm1(arm1), arm2(arm2), yaw(yaw) {} + + public: bool pose(int tYaw, int tArm1, int tArm2) { + /* Calculate the absolute distance to target */ + const int d1 = abs(tArm1 - arm1.angle()); + const int d2 = abs(tArm2 - arm2.angle()); + const int d3 = abs(tYaw - yaw.angle()); + + /* Rotate with according speeds */ + const int m = max(max(d1, d2), d3); + arm1.update(tArm1, 4 * (m / d1)); + arm2.update(tArm2, 4 * (m / d2)); + yaw.update(tYaw, 4 * (m / d3)); + + /* Is destination reached */ + return arm1.angle() == tArm1 + && arm2.angle() == tArm2 + && yaw.angle() == tYaw; + } + + public: bool point(float x, float y) { + /* Calculate pythagorean theorem */ + const float dist = sqrtf(x * x + y * y); + const int tYaw = (int) degrees(atan2f(x, y)); + float r = (dist / 2.0f) / size; + r = constrain(r, -1.0f, 1.0f); + + /* Calculate angles and rotate */ + const float a1 = degrees(acosf(r)); + const float a2 = (90.0f - a1) * 2.0f; + const int tArm1 = 90 - (int) a1; + const int tArm2 = (int) a2 - 90; + return pose(tYaw, tArm1, tArm2); + } + + public: bool reset() { + /* Rotate to origin */ + return pose(0, 0, 0); + } +}; \ No newline at end of file diff --git a/library.json b/library.json new file mode 100644 index 0000000..d40c917 --- /dev/null +++ b/library.json @@ -0,0 +1,9 @@ +{ + "name": "Robot", + "version": "1.0.0", + "description": "Robot Arm Controls", + "homepage": "https://zerozipp.dev", + "license": "MIT", + "frameworks": "*", + "platforms": "*" +} \ No newline at end of file