Skip to content

Commit

Permalink
WIP: HP: Allow prism-like setups instead of just pyramid-like setups
Browse files Browse the repository at this point in the history
3.5 HP: Change from bool to class and introduce None mode

3.5 HP: refactor out IsInsidePyramidSides

3.5 HP: refactor out IsInsidePrismSides
  • Loading branch information
jtimon committed Mar 10, 2023
1 parent a18141b commit 582347e
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 7 deletions.
41 changes: 34 additions & 7 deletions src/Movement/Kinematics/HangprinterKinematics.cpp
Expand Up @@ -99,6 +99,7 @@ void HangprinterKinematics::Init() noexcept
constexpr float DefaultTorqueConstants[HANGPRINTER_AXES] = { 0.0F };

ARRAY_INIT(anchors, DefaultAnchors);
anchorMode = HangprinterAnchorMode::LastOnTop;
printRadius = DefaultPrintRadius;
spoolBuildupFactor = DefaultSpoolBuildupFactor;
ARRAY_INIT(spoolRadii, DefaultSpoolRadii);
Expand Down Expand Up @@ -419,25 +420,51 @@ static bool isSameSide(float const v0[3], float const v1[3], float const v2[3],
return dot0*dot1 > 0.0F;
}

// For each triangle side in a pseudo-pyramid, check if the point is inside the pyramid (Except for the base)
// Also check that any point below the line between two exterior anchors (all anchors are exterior except for the last one)
// is in the "inside part" all the way down to min_Z, however low it may be.
// To further limit the movements in the X and Y axes one can simply set a smaller print radius.
bool HangprinterKinematics::IsReachable(float axesCoords[MaxAxes], AxesBitmap axes) const noexcept /*override*/
bool HangprinterKinematics::IsInsidePyramidSides(float const coords[3]) const noexcept
{
float const coords[3] = {axesCoords[X_AXIS], axesCoords[Y_AXIS], axesCoords[Z_AXIS]};
bool reachable = true;

// Check all the planes defined by triangle sides in the pyramid
for (size_t i = 0; reachable && i < HANGPRINTER_AXES - 1; ++i) {
reachable = reachable && isSameSide(anchors[i], anchors[(i+1) % (HANGPRINTER_AXES - 1)], anchors[HANGPRINTER_AXES - 1], anchors[(i+2) % (HANGPRINTER_AXES - 1)], coords);
}
return reachable;
}

bool HangprinterKinematics::IsInsidePrismSides(float const coords[3], unsigned const discount_last) const noexcept
{
bool reachable = true;

// For each side of the base, check the plane formed by side and another point bellow them in z.
for (size_t i = 0; reachable && i < HANGPRINTER_AXES - 1; ++i) {
for (size_t i = 0; reachable && i < HANGPRINTER_AXES - discount_last; ++i) {
float const lower_point[3] = {anchors[i][0], anchors[i][1], anchors[i][2] - 1};
reachable = reachable && isSameSide(anchors[i], anchors[(i+1) % (HANGPRINTER_AXES - 1)], lower_point, anchors[(i+2) % (HANGPRINTER_AXES - 1)], coords);
}
return reachable;
}

// For each triangle side in a pseudo-pyramid, check if the point is inside the pyramid (Except for the base)
// Also check that any point below the line between two exterior anchors (all anchors are exterior except for the last one)
// is in the "inside part" all the way down to min_Z, however low it may be.
// To further limit the movements in the X and Y axes one can simply set a smaller print radius.
bool HangprinterKinematics::IsReachable(float axesCoords[MaxAxes], AxesBitmap axes) const noexcept /*override*/
{
float const coords[3] = {axesCoords[X_AXIS], axesCoords[Y_AXIS], axesCoords[Z_AXIS]};
bool reachable = true;

switch (anchorMode) {
case HangprinterAnchorMode::None:
return true;

// This reaches a pyramid on top of the lower prism if the bed is below the lower anchors
case HangprinterAnchorMode::LastOnTop:
default:
reachable = reachable && IsInsidePyramidSides(coords);
reachable = reachable && IsInsidePrismSides(coords, 1);

case HangprinterAnchorMode::AllOnTop:
reachable = reachable && IsInsidePrismSides(coords, 0);
};

return reachable;
}
Expand Down
11 changes: 11 additions & 0 deletions src/Movement/Kinematics/HangprinterKinematics.h
Expand Up @@ -12,6 +12,13 @@

#if SUPPORT_HANGPRINTER

// Different modes can be configured for different tradeoffs in terms of printing volumes and speeds
enum class HangprinterAnchorMode {
None, // All is reacheable in None anchor mode as printing volume
LastOnTop, // (Default) Rsults in a pyramid plus a prism below if the lower anchors are above the printing bed
AllOnTop, // Result in a prism (speeds get limited, specially going down in Z)
};

class HangprinterKinematics : public RoundBedKinematics
{
public:
Expand Down Expand Up @@ -55,6 +62,9 @@ class HangprinterKinematics : public RoundBedKinematics
protected:
DECLARE_OBJECT_MODEL_WITH_ARRAYS

bool IsInsidePyramidSides(float const coords[3]) const noexcept;
bool IsInsidePrismSides(float const coords[3], unsigned const discount_last) const noexcept;

private:
// Basic facts about movement system
static constexpr size_t HANGPRINTER_AXES = 4;
Expand All @@ -71,6 +81,7 @@ class HangprinterKinematics : public RoundBedKinematics
void PrintParameters(const StringRef& reply) const noexcept; // Print all the parameters for debugging

// The real defaults are in the cpp file
HangprinterAnchorMode anchorMode = HangprinterAnchorMode::LastOnTop;
float printRadius = 0.0F;
float anchors[HANGPRINTER_AXES][3] = {{ 0.0, 0.0, 0.0},
{ 0.0, 0.0, 0.0},
Expand Down

0 comments on commit 582347e

Please sign in to comment.