implement basic arm class
This commit is contained in:
Executable
+89
@@ -0,0 +1,89 @@
|
|||||||
|
#include "Arm.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
Arm::Arm(const std::wstring& comPort) noexcept:
|
||||||
|
oSerialBus(comPort),
|
||||||
|
j0(
|
||||||
|
oSerialBus,
|
||||||
|
Vector3d::Y,
|
||||||
|
Vector3d::Up,
|
||||||
|
100.0, //mm
|
||||||
|
0.0,
|
||||||
|
125.0,
|
||||||
|
30.0,
|
||||||
|
180.0,
|
||||||
|
0.0,
|
||||||
|
nullptr
|
||||||
|
),
|
||||||
|
j1(
|
||||||
|
oSerialBus,
|
||||||
|
Vector3d::X,
|
||||||
|
Vector3d::Forward,
|
||||||
|
72.0, //mm
|
||||||
|
1.0,
|
||||||
|
48.0,
|
||||||
|
0.0,
|
||||||
|
120.0,
|
||||||
|
0.0,
|
||||||
|
&j0
|
||||||
|
),
|
||||||
|
j2(
|
||||||
|
oSerialBus,
|
||||||
|
Vector3d::X,
|
||||||
|
Vector3d::Forward,
|
||||||
|
95.0, //mm
|
||||||
|
2.0,
|
||||||
|
115.0,
|
||||||
|
0.0,
|
||||||
|
180.0,
|
||||||
|
0.0,
|
||||||
|
&j1
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!oSerialBus.isOpen()) {
|
||||||
|
std::cerr << "Serial bus is not open! Is the COM port busy?" << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Arm::assumeHomePose()
|
||||||
|
{
|
||||||
|
if (!j0.goHome(0.5)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!j1.goHome(0.5)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!j2.goHome(0.5)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arm::~Arm()
|
||||||
|
{
|
||||||
|
oSerialBus.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Arm::assumeHomePoseImmediate()
|
||||||
|
{
|
||||||
|
if (!j0.goHomeImmediate()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!j1.goHomeImmediate()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!j2.goHomeImmediate()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Arm::update(double frametime)
|
||||||
|
{
|
||||||
|
j0.update(frametime);
|
||||||
|
j1.update(frametime);
|
||||||
|
j2.update(frametime);
|
||||||
|
}
|
||||||
Executable
+24
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "ArmSegment.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Arm
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Arm(const std::wstring& comPort) noexcept;
|
||||||
|
Arm(const Arm& other) = delete;
|
||||||
|
Arm(Arm&& other) noexcept = default;
|
||||||
|
~Arm();
|
||||||
|
|
||||||
|
bool assumeHomePoseImmediate();
|
||||||
|
bool assumeHomePose();
|
||||||
|
|
||||||
|
void update(double frametime);
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSerialBus oSerialBus;
|
||||||
|
ArmSegment j0;
|
||||||
|
ArmSegment j1;
|
||||||
|
ArmSegment j2;
|
||||||
|
};
|
||||||
|
|
||||||
Executable
+113
@@ -0,0 +1,113 @@
|
|||||||
|
#include "ArmSegment.h"
|
||||||
|
#include "OSerialBus.h"
|
||||||
|
|
||||||
|
ArmSegment::ArmSegment(
|
||||||
|
OSerialBus& serialBus,
|
||||||
|
const Vector3d& rotationAxis,
|
||||||
|
const Vector3d& longitudinalAxis,
|
||||||
|
const double length,
|
||||||
|
const uint8_t motorIndex,
|
||||||
|
const double mechanicalToVirtualAngleOffset,
|
||||||
|
const double mechanicalMinAngle,
|
||||||
|
const double mechanicalMaxAngle,
|
||||||
|
const double homeAngle,
|
||||||
|
ArmSegment* parent
|
||||||
|
) noexcept :
|
||||||
|
rotationAxis(rotationAxis),
|
||||||
|
longitudinalAxis(longitudinalAxis),
|
||||||
|
length(length),
|
||||||
|
motor(
|
||||||
|
motorIndex,
|
||||||
|
serialBus,
|
||||||
|
virtualToMechanicalAngle(homeAngle),
|
||||||
|
mechanicalMinAngle,
|
||||||
|
mechanicalMaxAngle,
|
||||||
|
0.5
|
||||||
|
),
|
||||||
|
parent(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmSegment::goHome(const std::optional<double> speed) noexcept
|
||||||
|
{
|
||||||
|
return motor.moveTo(
|
||||||
|
virtualToMechanicalAngle(homeAngle),
|
||||||
|
speed
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ArmSegment::goHomeImmediate() noexcept
|
||||||
|
{
|
||||||
|
return motor.moveToImmediate(
|
||||||
|
virtualToMechanicalAngle(homeAngle)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmSegment::moveTo(const double theta, const std::optional<double> speed) noexcept
|
||||||
|
{
|
||||||
|
return motor.moveTo(
|
||||||
|
virtualToMechanicalAngle(theta),
|
||||||
|
speed
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ArmSegment::moveToImmediate(const double theta) noexcept
|
||||||
|
{
|
||||||
|
return motor.moveToImmediate(
|
||||||
|
virtualToMechanicalAngle(theta)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmSegment::moveBy(const double theta, const std::optional<double> speed) noexcept
|
||||||
|
{
|
||||||
|
return motor.moveBy(
|
||||||
|
virtualToMechanicalAngle(theta),
|
||||||
|
speed
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ArmSegment::moveByImmediate(const double theta) noexcept
|
||||||
|
{
|
||||||
|
return motor.moveByImmediate(
|
||||||
|
virtualToMechanicalAngle(theta)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmSegment::stopMoving() noexcept
|
||||||
|
{
|
||||||
|
return motor.stopMoving();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArmSegment::pauseMoving() noexcept
|
||||||
|
{
|
||||||
|
motor.pauseMoving();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArmSegment::resumeMoving() noexcept
|
||||||
|
{
|
||||||
|
motor.resumeMoving();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmSegment::assumeTargetPositionImmediately() noexcept
|
||||||
|
{
|
||||||
|
return motor.assumeTargetPositionImmediately();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArmSegment::update(const double frametime)
|
||||||
|
{
|
||||||
|
motor.update(frametime);
|
||||||
|
}
|
||||||
|
|
||||||
|
double ArmSegment::virtualToMechanicalAngle(const double virtualAngle)
|
||||||
|
{
|
||||||
|
return virtualAngle + mechanicalToVirtualAngleOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ArmSegment::mechanicalToVirtualAngle(const double hardwareAngle)
|
||||||
|
{
|
||||||
|
return hardwareAngle - mechanicalToVirtualAngleOffset;
|
||||||
|
}
|
||||||
Executable
+66
@@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Motor.h"
|
||||||
|
#include "Vector3d.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class OSerialBus;
|
||||||
|
|
||||||
|
class ArmSegment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ArmSegment(
|
||||||
|
OSerialBus& serialBus,
|
||||||
|
const Vector3d& rotationAxis,
|
||||||
|
const Vector3d& longitudinalAxis,
|
||||||
|
const double length,
|
||||||
|
const uint8_t motorIndex,
|
||||||
|
const double mechanicalToVirtualAngleOffset, // Mechanical angle at which this segment is neutral to its parent (assuming 0 degrees in virtual space)
|
||||||
|
const double mechanicalMinAngle,
|
||||||
|
const double mechanicalMaxAngle,
|
||||||
|
const double homeAngle,
|
||||||
|
ArmSegment* parent // May be nullptr
|
||||||
|
) noexcept;
|
||||||
|
|
||||||
|
ArmSegment(const ArmSegment& other) = delete;
|
||||||
|
ArmSegment(ArmSegment&& other) noexcept = default;
|
||||||
|
|
||||||
|
// Will return the motor to its home angle
|
||||||
|
bool goHome(const std::optional<double> speed) noexcept;
|
||||||
|
// Will return the motor to its home angle immediately (this is jerky and may damage the hardware long-term)
|
||||||
|
bool goHomeImmediate() noexcept;
|
||||||
|
|
||||||
|
// Will move the motor to the desired angle with ramp-up and controlled speed
|
||||||
|
bool moveTo(const double theta, const std::optional<double> speed) noexcept;
|
||||||
|
// Will move the motor instantly to the desired angle (this is jerky and may damage the hardware long-term)
|
||||||
|
bool moveToImmediate(const double theta) noexcept;
|
||||||
|
// Will move the motor by a specified angle with ramp-up and controlled speed
|
||||||
|
bool moveBy(const double theta, const std::optional<double> speed) noexcept;
|
||||||
|
// Will move the motor by a specified angle instantly (this is jerky and may damage the hardware long-term)
|
||||||
|
bool moveByImmediate(const double theta) noexcept;
|
||||||
|
bool stopMoving() noexcept;
|
||||||
|
void pauseMoving() noexcept;
|
||||||
|
void resumeMoving() noexcept;
|
||||||
|
// Will move the motor to its current target instantly (this is jerky and may damage the hardware long-term)
|
||||||
|
bool assumeTargetPositionImmediately() noexcept;
|
||||||
|
|
||||||
|
void update(const double frametime);
|
||||||
|
|
||||||
|
void setSpeed(const double speed) noexcept { motor.setSpeed(speed); };
|
||||||
|
double getMechanicalMinAngle() const { return motor.getMechanicalMinPosition(); };
|
||||||
|
double getMechanicalMaxAngle() const { return motor.getMechanicalMaxPosition(); };
|
||||||
|
double getSpeed() const noexcept { return motor.getSpeed(); };
|
||||||
|
ArmSegment* getParent() { return parent; };
|
||||||
|
ArmSegment const* getParent() const { return parent; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
double virtualToMechanicalAngle(const double virtualAngle);
|
||||||
|
double mechanicalToVirtualAngle(const double hardwareAngle);
|
||||||
|
|
||||||
|
Motor motor;
|
||||||
|
Vector3d rotationAxis;
|
||||||
|
Vector3d longitudinalAxis;
|
||||||
|
double length;
|
||||||
|
double mechanicalToVirtualAngleOffset;
|
||||||
|
double homeAngle;
|
||||||
|
ArmSegment* parent;
|
||||||
|
};
|
||||||
+3
-37
@@ -4,40 +4,9 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
MainLoop::MainLoop() noexcept:
|
MainLoop::MainLoop() noexcept:
|
||||||
oSerialBus(L"COM4"),
|
arm(L"COM4")
|
||||||
j0(
|
|
||||||
0,
|
|
||||||
oSerialBus,
|
|
||||||
0,
|
|
||||||
30.0,
|
|
||||||
180.0,
|
|
||||||
125.0
|
|
||||||
),
|
|
||||||
j1(
|
|
||||||
1,
|
|
||||||
oSerialBus,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
120.0,
|
|
||||||
51.0
|
|
||||||
),
|
|
||||||
j2(
|
|
||||||
2,
|
|
||||||
oSerialBus,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
180.0,
|
|
||||||
115.0
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
arm.assumeHomePoseImmediate();
|
||||||
if (!oSerialBus.isOpen()) {
|
|
||||||
std::cerr << "Serial bus is not open! Is the COM port busy?" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
j0.moveHomeImmediate();
|
|
||||||
j1.moveHomeImmediate();
|
|
||||||
j2.moveHomeImmediate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MainLoop& MainLoop::getInstance()
|
MainLoop& MainLoop::getInstance()
|
||||||
@@ -48,7 +17,6 @@ MainLoop& MainLoop::getInstance()
|
|||||||
|
|
||||||
MainLoop::~MainLoop() noexcept
|
MainLoop::~MainLoop() noexcept
|
||||||
{
|
{
|
||||||
oSerialBus.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainLoop::run()
|
void MainLoop::run()
|
||||||
@@ -59,9 +27,7 @@ void MainLoop::run()
|
|||||||
std::chrono::steady_clock::time_point begin = std::chrono::high_resolution_clock::now();
|
std::chrono::steady_clock::time_point begin = std::chrono::high_resolution_clock::now();
|
||||||
const double frametime = (begin - lastBegin).count() * 10e-7; // in milliseconds
|
const double frametime = (begin - lastBegin).count() * 10e-7; // in milliseconds
|
||||||
|
|
||||||
j0.update(frametime);
|
arm.update(frametime);
|
||||||
j1.update(frametime);
|
|
||||||
j2.update(frametime);
|
|
||||||
|
|
||||||
lastBegin = std::chrono::high_resolution_clock::now();
|
lastBegin = std::chrono::high_resolution_clock::now();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "OSerialBus.h"
|
#include "Arm.h"
|
||||||
#include "Motor.h"
|
|
||||||
|
|
||||||
// Singleton-class, use MainLoop::getInstance() to get the only instance of the runtime
|
// Singleton-class, use MainLoop::getInstance() to get the only instance of the runtime
|
||||||
class MainLoop
|
class MainLoop
|
||||||
@@ -15,10 +14,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
MainLoop() noexcept;
|
MainLoop() noexcept;
|
||||||
|
|
||||||
OSerialBus oSerialBus;
|
|
||||||
Motor j0;
|
|
||||||
Motor j1;
|
|
||||||
Motor j2;
|
|
||||||
|
|
||||||
bool isRunning = true;
|
bool isRunning = true;
|
||||||
|
|
||||||
|
Arm arm;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -143,15 +143,21 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="Arm.cpp" />
|
||||||
|
<ClCompile Include="ArmSegment.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="MainLoop.cpp" />
|
<ClCompile Include="MainLoop.cpp" />
|
||||||
<ClCompile Include="Motor.cpp" />
|
<ClCompile Include="Motor.cpp" />
|
||||||
<ClCompile Include="OSerialBus.cpp" />
|
<ClCompile Include="OSerialBus.cpp" />
|
||||||
|
<ClCompile Include="Vector3d.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Arm.h" />
|
||||||
|
<ClInclude Include="ArmSegment.h" />
|
||||||
<ClInclude Include="MainLoop.h" />
|
<ClInclude Include="MainLoop.h" />
|
||||||
<ClInclude Include="Motor.h" />
|
<ClInclude Include="Motor.h" />
|
||||||
<ClInclude Include="OSerialBus.h" />
|
<ClInclude Include="OSerialBus.h" />
|
||||||
|
<ClInclude Include="Vector3d.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|||||||
@@ -27,6 +27,15 @@
|
|||||||
<ClCompile Include="Motor.cpp">
|
<ClCompile Include="Motor.cpp">
|
||||||
<Filter>Quelldateien</Filter>
|
<Filter>Quelldateien</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="ArmSegment.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Vector3d.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Arm.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="MainLoop.h">
|
<ClInclude Include="MainLoop.h">
|
||||||
@@ -38,5 +47,14 @@
|
|||||||
<ClInclude Include="Motor.h">
|
<ClInclude Include="Motor.h">
|
||||||
<Filter>Headerdateien</Filter>
|
<Filter>Headerdateien</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="ArmSegment.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Vector3d.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Arm.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
+3
-26
@@ -12,7 +12,6 @@ Motor::Motor(
|
|||||||
const double initialPosition,
|
const double initialPosition,
|
||||||
const double mechanicalMinPosition,
|
const double mechanicalMinPosition,
|
||||||
const double mechanicalMaxPosition,
|
const double mechanicalMaxPosition,
|
||||||
const double homePosition,
|
|
||||||
const double initialSpeed
|
const double initialSpeed
|
||||||
) noexcept:
|
) noexcept:
|
||||||
index(index),
|
index(index),
|
||||||
@@ -21,8 +20,7 @@ Motor::Motor(
|
|||||||
targetPosition(currentPosition),
|
targetPosition(currentPosition),
|
||||||
moveStartPosition(currentPosition),
|
moveStartPosition(currentPosition),
|
||||||
mechanicalMinPosition(mechanicalMinPosition),
|
mechanicalMinPosition(mechanicalMinPosition),
|
||||||
mechanicalMaxPosition(mechanicalMaxPosition),
|
mechanicalMaxPosition(mechanicalMaxPosition)
|
||||||
homePosition(homePosition)
|
|
||||||
{
|
{
|
||||||
setSpeed(initialSpeed);
|
setSpeed(initialSpeed);
|
||||||
}
|
}
|
||||||
@@ -35,7 +33,6 @@ Motor::Motor(Motor&& other) noexcept:
|
|||||||
moveStartPosition(other.moveStartPosition),
|
moveStartPosition(other.moveStartPosition),
|
||||||
mechanicalMinPosition(other.mechanicalMinPosition),
|
mechanicalMinPosition(other.mechanicalMinPosition),
|
||||||
mechanicalMaxPosition(other.mechanicalMaxPosition),
|
mechanicalMaxPosition(other.mechanicalMaxPosition),
|
||||||
homePosition(other.homePosition),
|
|
||||||
targetSpeed(other.targetSpeed),
|
targetSpeed(other.targetSpeed),
|
||||||
speedLow(other.speedLow)
|
speedLow(other.speedLow)
|
||||||
{
|
{
|
||||||
@@ -130,26 +127,6 @@ bool Motor::moveByImmediate(const double theta) noexcept
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Motor::moveHome(const std::optional<double> speed) noexcept
|
|
||||||
{
|
|
||||||
if (disabled) {
|
|
||||||
std::cerr << "Trying to act on disabled motor object!" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return moveTo(homePosition, speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Motor::moveHomeImmediate() noexcept
|
|
||||||
{
|
|
||||||
if (disabled) {
|
|
||||||
std::cerr << "Trying to act on disabled motor object!" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return moveToImmediate(homePosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Motor::stopMoving() noexcept
|
bool Motor::stopMoving() noexcept
|
||||||
{
|
{
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
@@ -202,7 +179,7 @@ void Motor::update(const double frametime)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleRampUp(frametime);
|
handleMovement(frametime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Motor::setSpeed(const double speed) noexcept
|
void Motor::setSpeed(const double speed) noexcept
|
||||||
@@ -221,7 +198,7 @@ bool Motor::isPositionInMechanicalRange(const double pos) const noexcept
|
|||||||
return pos >= mechanicalMinPosition && pos <= mechanicalMaxPosition;
|
return pos >= mechanicalMinPosition && pos <= mechanicalMaxPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Motor::handleRampUp(const double frametime)
|
void Motor::handleMovement(const double frametime)
|
||||||
{
|
{
|
||||||
constexpr double epsilon = 0.1;
|
constexpr double epsilon = 0.1;
|
||||||
if (std::abs(currentPosition - targetPosition) > epsilon) {
|
if (std::abs(currentPosition - targetPosition) > epsilon) {
|
||||||
|
|||||||
+9
-8
@@ -11,23 +11,24 @@ public:
|
|||||||
const double initialPosition,
|
const double initialPosition,
|
||||||
const double mechanicalMinPosition,
|
const double mechanicalMinPosition,
|
||||||
const double mechanicalMaxPosition,
|
const double mechanicalMaxPosition,
|
||||||
const double homePosition,
|
|
||||||
const double initialSpeed = 0.5
|
const double initialSpeed = 0.5
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
Motor(const Motor& other) = delete;
|
Motor(const Motor& other) = delete;
|
||||||
Motor(Motor&& other) noexcept;
|
Motor(Motor&& other) noexcept;
|
||||||
|
|
||||||
// Will move the motor immediately to the desired position (don't do that)
|
// Will move the motor to the desired position with ramp-up and controlled speed
|
||||||
bool moveToImmediate(const double theta) noexcept;
|
|
||||||
bool moveTo(const double theta, const std::optional<double> speed) noexcept;
|
bool moveTo(const double theta, const std::optional<double> speed) noexcept;
|
||||||
|
// Will move the motor instantly to the desired position (this is jerky and may damage the hardware long-term)
|
||||||
|
bool moveToImmediate(const double theta) noexcept;
|
||||||
|
// Will move the motor by a specified angle with ramp-up and controlled speed
|
||||||
bool moveBy(const double theta, const std::optional<double> speed) noexcept;
|
bool moveBy(const double theta, const std::optional<double> speed) noexcept;
|
||||||
|
// Will move the motor by a specified angle instantly (this is jerky and may damage the hardware long-term)
|
||||||
bool moveByImmediate(const double theta) noexcept;
|
bool moveByImmediate(const double theta) noexcept;
|
||||||
bool moveHome(const std::optional<double> speed) noexcept;
|
|
||||||
bool moveHomeImmediate() noexcept;
|
|
||||||
bool stopMoving() noexcept;
|
bool stopMoving() noexcept;
|
||||||
void pauseMoving() noexcept;
|
void pauseMoving() noexcept;
|
||||||
void resumeMoving() noexcept;
|
void resumeMoving() noexcept;
|
||||||
|
// Will move the motor to its current target instantly (this is jerky and may damage the hardware long-term)
|
||||||
bool assumeTargetPositionImmediately() noexcept;
|
bool assumeTargetPositionImmediately() noexcept;
|
||||||
|
|
||||||
void update(const double frametime);
|
void update(const double frametime);
|
||||||
@@ -39,12 +40,13 @@ public:
|
|||||||
void setSpeed(const double speedTarget) noexcept;
|
void setSpeed(const double speedTarget) noexcept;
|
||||||
double getMechanicalMinPosition() const { return mechanicalMinPosition; };
|
double getMechanicalMinPosition() const { return mechanicalMinPosition; };
|
||||||
double getMechanicalMaxPosition() const { return mechanicalMaxPosition; };
|
double getMechanicalMaxPosition() const { return mechanicalMaxPosition; };
|
||||||
double getHomePosition() const { return homePosition; };
|
|
||||||
double getPaused() const { return paused; };
|
double getPaused() const { return paused; };
|
||||||
bool isPositionInMechanicalRange(const double pos) const noexcept;
|
bool isPositionInMechanicalRange(const double pos) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleRampUp(const double frametime);
|
// Update-handler for moving
|
||||||
|
void handleMovement(const double frametime);
|
||||||
|
// Sends a move absolute command to the serial busses MCU
|
||||||
bool sendMACommand(const double targetPos) noexcept;
|
bool sendMACommand(const double targetPos) noexcept;
|
||||||
// Will calculate the current speed for rampup based on currentPosition, moveStartPosition, and targetPosition
|
// Will calculate the current speed for rampup based on currentPosition, moveStartPosition, and targetPosition
|
||||||
double calculateCurrentSpeed() const noexcept;
|
double calculateCurrentSpeed() const noexcept;
|
||||||
@@ -58,7 +60,6 @@ private:
|
|||||||
double speedLow; // End- and startpoint of ramp-up phase
|
double speedLow; // End- and startpoint of ramp-up phase
|
||||||
const double mechanicalMinPosition;
|
const double mechanicalMinPosition;
|
||||||
const double mechanicalMaxPosition;
|
const double mechanicalMaxPosition;
|
||||||
const double homePosition;
|
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
bool paused = false;
|
bool paused = false;
|
||||||
};
|
};
|
||||||
|
|||||||
Executable
+160
@@ -0,0 +1,160 @@
|
|||||||
|
#include "Vector3d.h"
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
const Vector3d Vector3d::Zero { 0.0, 0.0, 0.0 };
|
||||||
|
const Vector3d Vector3d::One { 1.0, 1.0, 1.0 };
|
||||||
|
const Vector3d Vector3d::Forward { 0.0, 0.0, 1.0 };
|
||||||
|
const Vector3d Vector3d::Backward { 0.0, 0.0, -1.0 };
|
||||||
|
const Vector3d Vector3d::Up { 0.0, 1.0, 0.0 };
|
||||||
|
const Vector3d Vector3d::Down { 0.0, -1.0, 0.0 };
|
||||||
|
const Vector3d Vector3d::Left { -1.0, 0.0, 0.0 };
|
||||||
|
const Vector3d Vector3d::Right { 1.0, 0.0, 0.0 };
|
||||||
|
const Vector3d Vector3d::X { 1.0, 0.0, 0.0 };
|
||||||
|
const Vector3d Vector3d::Y { 0.0, 1.0, 0.0 };
|
||||||
|
const Vector3d Vector3d::Z { 0.0, 0.0, 1.0 };
|
||||||
|
|
||||||
|
Vector3d::Vector3d()
|
||||||
|
: x(0.0), y(0.0), z(0.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d::Vector3d(double x, double y, double z)
|
||||||
|
: x(x), y(y), z(z)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d& Vector3d::operator=(const Vector3d& other)
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
x = other.x;
|
||||||
|
y = other.y;
|
||||||
|
z = other.z;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d& Vector3d::operator=(Vector3d&& other) noexcept
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
x = other.x;
|
||||||
|
y = other.y;
|
||||||
|
z = other.z;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d Vector3d::operator+(const Vector3d& rhs) const
|
||||||
|
{
|
||||||
|
return { x + rhs.x, y + rhs.y, z + rhs.z };
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d Vector3d::operator-(const Vector3d& rhs) const
|
||||||
|
{
|
||||||
|
return { x - rhs.x, y - rhs.y, z - rhs.z };
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d Vector3d::operator*(double scalar) const
|
||||||
|
{
|
||||||
|
return { x * scalar, y * scalar, z * scalar };
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d Vector3d::operator/(double scalar) const
|
||||||
|
{
|
||||||
|
return { x / scalar, y / scalar, z / scalar };
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d& Vector3d::operator+=(const Vector3d& rhs)
|
||||||
|
{
|
||||||
|
x += rhs.x;
|
||||||
|
y += rhs.y;
|
||||||
|
z += rhs.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d& Vector3d::operator-=(const Vector3d& rhs)
|
||||||
|
{
|
||||||
|
x -= rhs.x;
|
||||||
|
y -= rhs.y;
|
||||||
|
z -= rhs.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d& Vector3d::operator*=(double scalar)
|
||||||
|
{
|
||||||
|
x *= scalar;
|
||||||
|
y *= scalar;
|
||||||
|
z *= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d& Vector3d::operator/=(double scalar)
|
||||||
|
{
|
||||||
|
x /= scalar;
|
||||||
|
y /= scalar;
|
||||||
|
z /= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Vector3d::operator==(const Vector3d& rhs) const
|
||||||
|
{
|
||||||
|
return x == rhs.x && y == rhs.y && z == rhs.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Vector3d::operator!=(const Vector3d& rhs) const
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const Vector3d& v)
|
||||||
|
{
|
||||||
|
os << "Vector3d(" << v.x << ", " << v.y << ", " << v.z << ")";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Vector3d::dot(const Vector3d& rhs) const
|
||||||
|
{
|
||||||
|
return x * rhs.x + y * rhs.y + z * rhs.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Vector3d::magnitude() const
|
||||||
|
{
|
||||||
|
return std::sqrt(x * x + y * y + z * z);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Vector3d::magnitudeSquared() const
|
||||||
|
{
|
||||||
|
return x * x + y * y + z * z;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d Vector3d::cross(const Vector3d& rhs) const
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
y * rhs.z - z * rhs.y,
|
||||||
|
z * rhs.x - x * rhs.z,
|
||||||
|
x * rhs.y - y * rhs.x
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d Vector3d::normalized() const
|
||||||
|
{
|
||||||
|
double m = magnitude();
|
||||||
|
if (m == 0.0)
|
||||||
|
return Vector3d::Zero;
|
||||||
|
|
||||||
|
double inv = 1.0 / m;
|
||||||
|
return { x * inv, y * inv, z * inv };
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vector3d::normalize()
|
||||||
|
{
|
||||||
|
double m = magnitude();
|
||||||
|
if (m == 0.0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double inv = 1.0 / m;
|
||||||
|
x *= inv;
|
||||||
|
y *= inv;
|
||||||
|
z *= inv;
|
||||||
|
}
|
||||||
Executable
+59
@@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
class Vector3d
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double z;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Vector3d();
|
||||||
|
Vector3d(double x, double y, double z);
|
||||||
|
|
||||||
|
Vector3d(const Vector3d& other) = default;
|
||||||
|
Vector3d(Vector3d&& other) noexcept = default;
|
||||||
|
|
||||||
|
|
||||||
|
double dot(const Vector3d& rhs) const;
|
||||||
|
double magnitude() const;
|
||||||
|
double magnitudeSquared() const;
|
||||||
|
Vector3d cross(const Vector3d& rhs) const;
|
||||||
|
Vector3d normalized() const;
|
||||||
|
void normalize();
|
||||||
|
|
||||||
|
Vector3d& operator=(const Vector3d& other);
|
||||||
|
Vector3d& operator=(Vector3d&& other) noexcept;
|
||||||
|
|
||||||
|
Vector3d operator+(const Vector3d& rhs) const;
|
||||||
|
Vector3d operator-(const Vector3d& rhs) const;
|
||||||
|
|
||||||
|
Vector3d operator*(double scalar) const;
|
||||||
|
Vector3d operator/(double scalar) const;
|
||||||
|
|
||||||
|
Vector3d& operator+=(const Vector3d& rhs);
|
||||||
|
Vector3d& operator-=(const Vector3d& rhs);
|
||||||
|
|
||||||
|
Vector3d& operator*=(double scalar);
|
||||||
|
Vector3d& operator/=(double scalar);
|
||||||
|
|
||||||
|
bool operator==(const Vector3d& rhs) const;
|
||||||
|
bool operator!=(const Vector3d& rhs) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const Vector3d Zero;
|
||||||
|
static const Vector3d One;
|
||||||
|
static const Vector3d Forward;
|
||||||
|
static const Vector3d Backward;
|
||||||
|
static const Vector3d Up;
|
||||||
|
static const Vector3d Down;
|
||||||
|
static const Vector3d Left;
|
||||||
|
static const Vector3d Right;
|
||||||
|
static const Vector3d X;
|
||||||
|
static const Vector3d Y;
|
||||||
|
static const Vector3d Z;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const Vector3d& v);
|
||||||
Reference in New Issue
Block a user