Skip to content

Commit

Permalink
HP: Allow custom and prism-like setups instead of just pyramid-like s…
Browse files Browse the repository at this point in the history
…etups

- Change from bool to class and introduce None mode for
custom (experimental) setups (all allowed)

- refactor out IsInsidePyramidSides

- refactor out IsInsidePrismSides

- introduce HangprinterAnchorMode::LastOnTop for prism-like setups
  with all anchors on top

- introduce a T parameter in M666 to configure the anchor mode
  • Loading branch information
jtimon committed Mar 20, 2023
1 parent d2a3672 commit d51a945
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 9 deletions.
52 changes: 43 additions & 9 deletions src/Movement/Kinematics/HangprinterKinematics.cpp
Original file line number Diff line number Diff line change
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 @@ -229,6 +230,12 @@ bool HangprinterKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const
}
else if (mCode == 666)
{
// 0=None, 1=last-top, 2=all-top, 3-half-top, etc
uint32_t unsignedAnchorMode = (uint32_t)anchorMode;
gb.TryGetUIValue('T', unsignedAnchorMode, seen);
if (unsignedAnchorMode <= (uint32_t)HangprinterAnchorMode::AllOnTop) {
anchorMode = (HangprinterAnchorMode)unsignedAnchorMode;
}
gb.TryGetFValue('Q', spoolBuildupFactor, seen);
gb.TryGetFloatArray('R', HANGPRINTER_AXES, spoolRadii, seen);
gb.TryGetUIArray('U', HANGPRINTER_AXES, mechanicalAdvantage, seen);
Expand All @@ -248,7 +255,8 @@ bool HangprinterKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const
}
else
{
reply.printf("M666 Q%.4f\n", (double)spoolBuildupFactor);
// TODO T is taken, find a letter that's free
reply.printf("M666 T%u Q%.4f\n", (unsigned)anchorMode, (double)spoolBuildupFactor);

reply.lcatf("R%.2f", (double)spoolRadii[0]);
for (size_t i = 1; i < HANGPRINTER_AXES; ++i)
Expand Down Expand Up @@ -444,25 +452,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 = IsInsidePyramidSides(coords);
return reachable && IsInsidePrismSides(coords, 1);

case HangprinterAnchorMode::AllOnTop:
return IsInsidePrismSides(coords, 0);
};

return reachable;
}
Expand Down Expand Up @@ -586,7 +620,7 @@ bool HangprinterKinematics::WriteCalibrationParameters(FileStore *f) const noexc
ok = f->Write(scratchString.c_str());
if (!ok) return false;

scratchString.printf("M666 Q%.6f ", (double)spoolBuildupFactor);
scratchString.printf("M666 T%u Q%.6f ", (unsigned)anchorMode, (double)spoolBuildupFactor);
ok = f->Write(scratchString.c_str());
if (!ok) return false;

Expand Down
11 changes: 11 additions & 0 deletions src/Movement/Kinematics/HangprinterKinematics.h
Original file line number Diff line number Diff line change
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
const char* ANCHOR_CHARS = "ABCD";
Expand All @@ -72,6 +82,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 d51a945

Please sign in to comment.