Skip to content

Commit 7101a2c

Browse files
committed
WIP: HP: Allow prism-like setups instead of just pyramid-like setups
3.5 HP: Change from bool to class and introduce None mode 3.5 HP: refactor out IsInsidePyramidSides 3.5 HP: refactor out IsInsidePrismSides
1 parent e12f7b8 commit 7101a2c

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

src/Movement/Kinematics/HangprinterKinematics.cpp

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ void HangprinterKinematics::Init() noexcept
9999
constexpr float DefaultTorqueConstants[HANGPRINTER_AXES] = { 0.0F };
100100

101101
ARRAY_INIT(anchors, DefaultAnchors);
102+
anchorMode = HangprinterAnchorMode::LastOnTop;
102103
printRadius = DefaultPrintRadius;
103104
spoolBuildupFactor = DefaultSpoolBuildupFactor;
104105
ARRAY_INIT(spoolRadii, DefaultSpoolRadii);
@@ -229,6 +230,8 @@ bool HangprinterKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const
229230
}
230231
else if (mCode == 666)
231232
{
233+
// 0=None, 1=last-top, 2=all-top, 3-half-top, etc
234+
gb.TryGetUIValue('T', (uint32_t&)anchorMode, seen);
232235
gb.TryGetFValue('Q', spoolBuildupFactor, seen);
233236
gb.TryGetFloatArray('R', HANGPRINTER_AXES, spoolRadii, seen);
234237
gb.TryGetUIArray('U', HANGPRINTER_AXES, mechanicalAdvantage, seen);
@@ -470,25 +473,51 @@ static bool isSameSide(float const v0[3], float const v1[3], float const v2[3],
470473
return dot0*dot1 > 0.0F;
471474
}
472475

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

482480
// Check all the planes defined by triangle sides in the pyramid
483481
for (size_t i = 0; reachable && i < HANGPRINTER_AXES - 1; ++i) {
484482
reachable = reachable && isSameSide(anchors[i], anchors[(i+1) % (HANGPRINTER_AXES - 1)], anchors[HANGPRINTER_AXES - 1], anchors[(i+2) % (HANGPRINTER_AXES - 1)], coords);
485483
}
484+
return reachable;
485+
}
486+
487+
bool HangprinterKinematics::IsInsidePrismSides(float const coords[3], unsigned const discount_last) const noexcept
488+
{
489+
bool reachable = true;
486490

487491
// For each side of the base, check the plane formed by side and another point bellow them in z.
488-
for (size_t i = 0; reachable && i < HANGPRINTER_AXES - 1; ++i) {
492+
for (size_t i = 0; reachable && i < HANGPRINTER_AXES - discount_last; ++i) {
489493
float const lower_point[3] = {anchors[i][0], anchors[i][1], anchors[i][2] - 1};
490494
reachable = reachable && isSameSide(anchors[i], anchors[(i+1) % (HANGPRINTER_AXES - 1)], lower_point, anchors[(i+2) % (HANGPRINTER_AXES - 1)], coords);
491495
}
496+
return reachable;
497+
}
498+
499+
// For each triangle side in a pseudo-pyramid, check if the point is inside the pyramid (Except for the base)
500+
// Also check that any point below the line between two exterior anchors (all anchors are exterior except for the last one)
501+
// is in the "inside part" all the way down to min_Z, however low it may be.
502+
// To further limit the movements in the X and Y axes one can simply set a smaller print radius.
503+
bool HangprinterKinematics::IsReachable(float axesCoords[MaxAxes], AxesBitmap axes) const noexcept /*override*/
504+
{
505+
float const coords[3] = {axesCoords[X_AXIS], axesCoords[Y_AXIS], axesCoords[Z_AXIS]};
506+
bool reachable = true;
507+
508+
switch (anchorMode) {
509+
case HangprinterAnchorMode::None:
510+
return true;
511+
512+
// This reaches a pyramid on top of the lower prism if the bed is below the lower anchors
513+
case HangprinterAnchorMode::LastOnTop:
514+
default:
515+
reachable = reachable && IsInsidePyramidSides(coords);
516+
reachable = reachable && IsInsidePrismSides(coords, 1);
517+
518+
case HangprinterAnchorMode::AllOnTop:
519+
reachable = reachable && IsInsidePrismSides(coords, 0);
520+
};
492521

493522
return reachable;
494523
}

src/Movement/Kinematics/HangprinterKinematics.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@
1212

1313
#if SUPPORT_HANGPRINTER
1414

15+
// Different modes can be configured for different tradeoffs in terms of printing volumes and speeds
16+
enum class HangprinterAnchorMode {
17+
None, // All is reacheable in None anchor mode as printing volume
18+
LastOnTop, // (Default) Rsults in a pyramid plus a prism below if the lower anchors are above the printing bed
19+
AllOnTop, // Result in a prism (speeds get limited, specially going down in Z)
20+
};
21+
1522
class HangprinterKinematics : public RoundBedKinematics
1623
{
1724
public:
@@ -55,6 +62,9 @@ class HangprinterKinematics : public RoundBedKinematics
5562
protected:
5663
DECLARE_OBJECT_MODEL_WITH_ARRAYS
5764

65+
bool IsInsidePyramidSides(float const coords[3]) const noexcept;
66+
bool IsInsidePrismSides(float const coords[3], unsigned const discount_last) const noexcept;
67+
5868
private:
5969
// Basic facts about movement system
6070
const char* ANCHOR_CHARS = "ABCD";
@@ -72,6 +82,7 @@ class HangprinterKinematics : public RoundBedKinematics
7282
void PrintParameters(const StringRef& reply) const noexcept; // Print all the parameters for debugging
7383

7484
// The real defaults are in the cpp file
85+
HangprinterAnchorMode anchorMode = HangprinterAnchorMode::LastOnTop;
7586
float printRadius = 0.0F;
7687
float anchors[HANGPRINTER_AXES][3] = {{ 0.0, 0.0, 0.0},
7788
{ 0.0, 0.0, 0.0},

0 commit comments

Comments
 (0)