@@ -129,16 +129,15 @@ void HangprinterKinematics::Recalc() noexcept
129129
130130 // This is the difference between a "line length" and a "line position"
131131 // "line length" == ("line position" + "line length in origin")
132- distancesOrigin[A_AXIS] = fastSqrtf (fsquare (anchors[A_AXIS][0 ]) + fsquare (anchors[A_AXIS][1 ]) + fsquare (anchors[A_AXIS][2 ]));
133- distancesOrigin[B_AXIS] = fastSqrtf (fsquare (anchors[B_AXIS][0 ]) + fsquare (anchors[B_AXIS][1 ]) + fsquare (anchors[B_AXIS][2 ]));
134- distancesOrigin[C_AXIS] = fastSqrtf (fsquare (anchors[C_AXIS][0 ]) + fsquare (anchors[C_AXIS][1 ]) + fsquare (anchors[C_AXIS][2 ]));
135- distancesOrigin[D_AXIS] = fastSqrtf (fsquare (anchors[D_AXIS][0 ]) + fsquare (anchors[D_AXIS][1 ]) + fsquare (anchors[D_AXIS][2 ]));
136-
132+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
133+ {
134+ distancesOrigin[i] = fastSqrtf (fsquare (anchors[i][0 ]) + fsquare (anchors[i][1 ]) + fsquare (anchors[i][2 ]));
135+ }
137136
138137 // // Line buildup compensation
139138 float stepsPerUnitTimesRTmp[HANGPRINTER_AXES] = { 0.0 };
140139 Platform& platform = reprap.GetPlatform (); // No const because we want to set drive steper per unit
141- for (size_t i = 0 ; i < HANGPRINTER_AXES; i++ )
140+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i )
142141 {
143142 const uint8_t driver = platform.GetAxisDriversConfig (i).driverNumbers [0 ].localDriver ; // Only supports single driver
144143 bool dummy;
@@ -203,11 +202,10 @@ bool HangprinterKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const
203202 if (mCode == 669 )
204203 {
205204 const bool seenNonGeometry = TryConfigureSegmentation (gb);
206- gb.TryGetFloatArray (' A' , 3 , anchors[A_AXIS], seen);
207- gb.TryGetFloatArray (' B' , 3 , anchors[B_AXIS], seen);
208- gb.TryGetFloatArray (' C' , 3 , anchors[C_AXIS], seen);
209- gb.TryGetFloatArray (' D' , 3 , anchors[D_AXIS], seen);
210-
205+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
206+ {
207+ gb.TryGetFloatArray (ANCHOR_CHARS[i], 3 , anchors[i], seen);
208+ }
211209 if (gb.Seen (' P' ))
212210 {
213211 printRadius = gb.GetPositiveFValue ();
@@ -221,18 +219,12 @@ bool HangprinterKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const
221219 else if (!seenNonGeometry && !gb.Seen (' K' ))
222220 {
223221 Kinematics::Configure (mCode , gb, reply, error);
224- reply.lcatf (
225- " A:%.2f, %.2f, %.2f\n "
226- " B:%.2f, %.2f, %.2f\n "
227- " C:%.2f, %.2f, %.2f\n "
228- " D:%.2f, %.2f, %.2f\n "
229- " P:Print radius: %.1f" ,
230- (double )anchors[A_AXIS][X_AXIS], (double )anchors[A_AXIS][Y_AXIS], (double )anchors[A_AXIS][Z_AXIS],
231- (double )anchors[B_AXIS][X_AXIS], (double )anchors[B_AXIS][Y_AXIS], (double )anchors[B_AXIS][Z_AXIS],
232- (double )anchors[C_AXIS][X_AXIS], (double )anchors[C_AXIS][Y_AXIS], (double )anchors[C_AXIS][Z_AXIS],
233- (double )anchors[D_AXIS][X_AXIS], (double )anchors[D_AXIS][Y_AXIS], (double )anchors[D_AXIS][Z_AXIS],
234- (double )printRadius
235- );
222+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
223+ {
224+ reply.lcatf (" %c:%.2f, %.2f, %.2f" ,
225+ ANCHOR_CHARS[i], (double )anchors[i][X_AXIS], (double )anchors[i][Y_AXIS], (double )anchors[i][Z_AXIS]);
226+ }
227+ reply.lcatf (" P:Print radius: %.1f" , (double )printRadius);
236228 }
237229 }
238230 else if (mCode == 666 )
@@ -256,36 +248,97 @@ bool HangprinterKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const
256248 }
257249 else
258250 {
259- reply.printf (
260- " M666 Q%.4f\n "
261- " R%.2f:%.2f:%.2f:%.2f\n "
262- " U%d:%d:%d:%d\n "
263- " O%d:%d:%d:%d\n "
264- " L%d:%d:%d:%d\n "
265- " H%d:%d:%d:%d\n "
266- " J%d:%d:%d:%d\n "
267- " W%.2f\n "
268- " S%.2f\n "
269- " I%.1f:%.1f:%.1f:%.1f\n "
270- " X%.1f:%.1f:%.1f:%.1f\n "
271- " Y%.1f:%.1f:%.1f:%.1f\n "
272- " T%.1f\n "
273- " C%.4f:%.4f:%.4f:%.4f" ,
274- (double )spoolBuildupFactor,
275- (double )spoolRadii[A_AXIS], (double )spoolRadii[B_AXIS], (double )spoolRadii[C_AXIS], (double )spoolRadii[D_AXIS],
276- (int )mechanicalAdvantage[A_AXIS], (int )mechanicalAdvantage[B_AXIS], (int )mechanicalAdvantage[C_AXIS], (int )mechanicalAdvantage[D_AXIS],
277- (int )linesPerSpool[A_AXIS], (int )linesPerSpool[B_AXIS], (int )linesPerSpool[C_AXIS], (int )linesPerSpool[D_AXIS],
278- (int )motorGearTeeth[A_AXIS], (int )motorGearTeeth[B_AXIS], (int )motorGearTeeth[C_AXIS], (int )motorGearTeeth[D_AXIS],
279- (int )spoolGearTeeth[A_AXIS], (int )spoolGearTeeth[B_AXIS], (int )spoolGearTeeth[C_AXIS], (int )spoolGearTeeth[D_AXIS],
280- (int )fullStepsPerMotorRev[A_AXIS], (int )fullStepsPerMotorRev[B_AXIS], (int )fullStepsPerMotorRev[C_AXIS], (int )fullStepsPerMotorRev[D_AXIS],
281- (double )moverWeight_kg,
282- (double )springKPerUnitLength,
283- (double )minPlannedForce_Newton[A_AXIS], (double )minPlannedForce_Newton[B_AXIS], (double )minPlannedForce_Newton[C_AXIS], (double )minPlannedForce_Newton[D_AXIS],
284- (double )maxPlannedForce_Newton[A_AXIS], (double )maxPlannedForce_Newton[B_AXIS], (double )maxPlannedForce_Newton[C_AXIS], (double )maxPlannedForce_Newton[D_AXIS],
285- (double )guyWireLengths[A_AXIS], (double )guyWireLengths[B_AXIS], (double )guyWireLengths[C_AXIS], (double )guyWireLengths[D_AXIS],
286- (double )targetForce_Newton,
287- (double )torqueConstants[A_AXIS], (double )torqueConstants[B_AXIS], (double )torqueConstants[C_AXIS], (double )torqueConstants[D_AXIS]
288- );
251+ reply.printf (" M666 Q%.4f\n " , (double )spoolBuildupFactor);
252+ reply.lcat (" R:Spool r " );
253+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
254+ {
255+ if (i != 0 ) {
256+ reply.cat (" , " );
257+ }
258+ reply.catf (" %.2f" , (double )spoolRadii[i]);
259+ }
260+ reply.lcat (" U:Mech Adv " );
261+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
262+ {
263+ if (i != 0 ) {
264+ reply.cat (" , " );
265+ }
266+ reply.catf (" %d" , (int )mechanicalAdvantage[i]);
267+ }
268+ reply.lcat (" O:Lines/spool " );
269+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
270+ {
271+ if (i != 0 ) {
272+ reply.cat (" , " );
273+ }
274+ reply.catf (" %d" , (int )linesPerSpool[i]);
275+ }
276+ reply.lcat (" L:Motor gear teeth " );
277+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
278+ {
279+ if (i != 0 ) {
280+ reply.cat (" , " );
281+ }
282+ reply.catf (" %d" , (int )motorGearTeeth[i]);
283+ }
284+ reply.lcat (" H:Spool gear teeth " );
285+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
286+ {
287+ if (i != 0 ) {
288+ reply.cat (" , " );
289+ }
290+ reply.catf (" %d" , (int )spoolGearTeeth[i]);
291+ }
292+ reply.lcat (" J:Full steps/rev " );
293+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
294+ {
295+ if (i != 0 ) {
296+ reply.cat (" , " );
297+ }
298+ reply.catf (" %d" , (int )fullStepsPerMotorRev[i]);
299+ }
300+
301+ reply.lcatf (" W %.2f\n " , (double )moverWeight_kg);
302+ reply.lcatf (" S %.2f\n " , (double )springKPerUnitLength);
303+
304+ reply.lcat (" I%.1f:%.1f:%.1f:%.1f\n " );
305+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
306+ {
307+ if (i != 0 ) {
308+ reply.cat (" , " );
309+ }
310+ reply.catf (" %d" , (int )minPlannedForce_Newton[i]);
311+ }
312+
313+ reply.lcat (" X%.1f:%.1f:%.1f:%.1f\n " );
314+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
315+ {
316+ if (i != 0 ) {
317+ reply.cat (" , " );
318+ }
319+ reply.catf (" %d" , (int )maxPlannedForce_Newton[i]);
320+ }
321+
322+ reply.lcat (" Y%.1f:%.1f:%.1f:%.1f\n " );
323+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
324+ {
325+ if (i != 0 ) {
326+ reply.cat (" , " );
327+ }
328+ reply.catf (" %d" , (int )guyWireLengths[i]);
329+ }
330+
331+ reply.lcatf (" T%.1f\n " , (double )targetForce_Newton);
332+
333+ reply.lcat (" C%.4f:%.4f:%.4f:%.4f\n " );
334+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
335+ {
336+ if (i != 0 ) {
337+ reply.cat (" , " );
338+ }
339+ reply.catf (" %d" , (int )torqueConstants[i]);
340+ }
341+
289342 }
290343 }
291344 else
@@ -300,11 +353,9 @@ bool HangprinterKinematics::CartesianToMotorSteps(const float machinePos[], cons
300353 size_t numVisibleAxes, size_t numTotalAxes, int32_t motorPos[], bool isCoordinated) const noexcept
301354{
302355 float distances[HANGPRINTER_AXES];
303- distances[A_AXIS] = hyp3 (machinePos, anchors[A_AXIS]);
304- distances[B_AXIS] = hyp3 (machinePos, anchors[B_AXIS]);
305- distances[C_AXIS] = hyp3 (machinePos, anchors[C_AXIS]);
306- distances[D_AXIS] = hyp3 (machinePos, anchors[D_AXIS]);
307-
356+ for (size_t i{0 }; i < HANGPRINTER_AXES; ++i) {
357+ distances[i] = hyp3 (machinePos, anchors[i]);
358+ }
308359
309360 float springKs[HANGPRINTER_AXES];
310361 for (size_t i{0 }; i < HANGPRINTER_AXES; ++i) {
@@ -325,10 +376,10 @@ bool HangprinterKinematics::CartesianToMotorSteps(const float machinePos[], cons
325376 linePos[i] = relaxedSpringLengths[i] - relaxedSpringLengthsOrigin[i];
326377 }
327378
328- motorPos[A_AXIS] = lrintf (k0[A_AXIS] * ( fastSqrtf (spoolRadiiSq[A_AXIS] + linePos[A_AXIS] * k2[A_AXIS]) - spoolRadii[A_AXIS]));
329- motorPos[B_AXIS] = lrintf (k0[B_AXIS] * ( fastSqrtf (spoolRadiiSq[B_AXIS] + linePos[B_AXIS] * k2[B_AXIS]) - spoolRadii[B_AXIS]));
330- motorPos[C_AXIS ] = lrintf (k0[C_AXIS ] * (fastSqrtf (spoolRadiiSq[C_AXIS ] + linePos[C_AXIS ] * k2[C_AXIS ]) - spoolRadii[C_AXIS ]));
331- motorPos[D_AXIS] = lrintf (k0[D_AXIS] * ( fastSqrtf (spoolRadiiSq[D_AXIS] + linePos[D_AXIS] * k2[D_AXIS]) - spoolRadii[D_AXIS]));
379+ for ( size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
380+ {
381+ motorPos[i ] = lrintf (k0[i ] * (fastSqrtf (spoolRadiiSq[i ] + linePos[i ] * k2[i ]) - spoolRadii[i ]));
382+ }
332383
333384 return true ;
334385}
@@ -555,54 +606,90 @@ bool HangprinterKinematics::WriteCalibrationParameters(FileStore *f) const noexc
555606 ok = f->Write (scratchString.c_str ());
556607 if (!ok) return false ;
557608
558- scratchString.printf (" R%.3f:%.3f:%.3f:%.3f" , (double )spoolRadii[A_AXIS], (double )spoolRadii[B_AXIS], (double )spoolRadii[C_AXIS], (double )spoolRadii[D_AXIS]);
609+ scratchString.printf (" R%.3f" , (double )spoolRadii[0 ]);
610+ for (size_t i = 1 ; i < HANGPRINTER_AXES; ++i)
611+ {
612+ scratchString.catf (" :%.3f" , (double )spoolRadii[i]);
613+ }
559614 ok = f->Write (scratchString.c_str ());
560615 if (!ok) return false ;
561616
562- scratchString.printf (" U%d:%d:%d:%d" , (int )mechanicalAdvantage[A_AXIS], (int )mechanicalAdvantage[B_AXIS], (int )mechanicalAdvantage[C_AXIS], (int )mechanicalAdvantage[D_AXIS]);
617+ scratchString.printf (" U%.3f" , (double )mechanicalAdvantage[0 ]);
618+ for (size_t i = 1 ; i < HANGPRINTER_AXES; ++i)
619+ {
620+ scratchString.catf (" :%.3f" , (double )mechanicalAdvantage[i]);
621+ }
563622 ok = f->Write (scratchString.c_str ());
564623 if (!ok) return false ;
565624
566- scratchString.printf (" O%d:%d:%d:%d" , (int )linesPerSpool[A_AXIS], (int )linesPerSpool[B_AXIS], (int )linesPerSpool[C_AXIS], (int )linesPerSpool[D_AXIS]);
625+ scratchString.printf (" O%.3f" , (double )linesPerSpool[0 ]);
626+ for (size_t i = 1 ; i < HANGPRINTER_AXES; ++i)
627+ {
628+ scratchString.catf (" :%.3f" , (double )linesPerSpool[i]);
629+ }
567630 ok = f->Write (scratchString.c_str ());
568631 if (!ok) return false ;
569632
570- scratchString.printf (" L%d:%d:%d:%d" , (int )motorGearTeeth[A_AXIS], (int )motorGearTeeth[B_AXIS], (int )motorGearTeeth[C_AXIS], (int )motorGearTeeth[D_AXIS]);
633+ scratchString.printf (" L%.3f" , (double )motorGearTeeth[0 ]);
634+ for (size_t i = 1 ; i < HANGPRINTER_AXES; ++i)
635+ {
636+ scratchString.catf (" :%.3f" , (double )motorGearTeeth[i]);
637+ }
571638 ok = f->Write (scratchString.c_str ());
572639 if (!ok) return false ;
573640
574- scratchString.printf (" H%d:%d:%d:%d" , (int )motorGearTeeth[A_AXIS], (int )motorGearTeeth[B_AXIS], (int )motorGearTeeth[C_AXIS], (int )motorGearTeeth[D_AXIS]);
641+ scratchString.printf (" H%.3f" , (double )spoolGearTeeth[0 ]);
642+ for (size_t i = 1 ; i < HANGPRINTER_AXES; ++i)
643+ {
644+ scratchString.catf (" :%.3f" , (double )spoolGearTeeth[i]);
645+ }
575646 ok = f->Write (scratchString.c_str ());
576647 if (!ok) return false ;
577648
578- scratchString.printf (" J%d:%d:%d:%d" , (int )fullStepsPerMotorRev[A_AXIS], (int )fullStepsPerMotorRev[B_AXIS], (int )fullStepsPerMotorRev[C_AXIS], (int )fullStepsPerMotorRev[D_AXIS]);
649+ scratchString.printf (" J%.3f" , (double )fullStepsPerMotorRev[0 ]);
650+ for (size_t i = 1 ; i < HANGPRINTER_AXES; ++i)
651+ {
652+ scratchString.catf (" :%.3f" , (double )fullStepsPerMotorRev[i]);
653+ }
579654 ok = f->Write (scratchString.c_str ());
580- if (!ok) return false ;
581655
582656 scratchString.printf (" W%.2f S%.2f" , (double )moverWeight_kg, (double )springKPerUnitLength);
583657 ok = f->Write (scratchString.c_str ());
584658 if (!ok) return false ;
585659
586- scratchString.printf (" I%.1f:%.1f:%.1f:%.1f" ,
587- (double )minPlannedForce_Newton[A_AXIS], (double )minPlannedForce_Newton[B_AXIS], (double )minPlannedForce_Newton[C_AXIS], (double )minPlannedForce_Newton[D_AXIS]);
660+ scratchString.printf (" I%.1f" , (double )minPlannedForce_Newton[0 ]);
661+ for (size_t i = 1 ; i < HANGPRINTER_AXES; ++i)
662+ {
663+ scratchString.catf (" :%.1f" , (double )minPlannedForce_Newton[i]);
664+ }
588665 ok = f->Write (scratchString.c_str ());
589666 if (!ok) return false ;
590667
591- scratchString.printf (" X%.1f:%.1f:%.1f:%.1f" ,
592- (double )maxPlannedForce_Newton[A_AXIS], (double )maxPlannedForce_Newton[B_AXIS], (double )maxPlannedForce_Newton[C_AXIS], (double )maxPlannedForce_Newton[D_AXIS]);
668+ scratchString.printf (" X%.1f" , (double )maxPlannedForce_Newton[0 ]);
669+ for (size_t i = 1 ; i < HANGPRINTER_AXES; ++i)
670+ {
671+ scratchString.catf (" :%.1f" , (double )maxPlannedForce_Newton[i]);
672+ }
593673 ok = f->Write (scratchString.c_str ());
594674 if (!ok) return false ;
595675
596- scratchString.printf (" Y%.1f:%.1f:%.1f:%.1f" ,
597- (double )guyWireLengths[A_AXIS], (double )guyWireLengths[B_AXIS], (double )guyWireLengths[C_AXIS], (double )guyWireLengths[D_AXIS]);
676+ scratchString.printf (" Y%.1f" , (double )guyWireLengths[0 ]);
677+ for (size_t i = 1 ; i < HANGPRINTER_AXES; ++i)
678+ {
679+ scratchString.catf (" :%.1f" , (double )guyWireLengths[i]);
680+ }
598681 ok = f->Write (scratchString.c_str ());
599682 if (!ok) return false ;
600683
601684 scratchString.printf (" T%.1f" , (double )targetForce_Newton);
602685 ok = f->Write (scratchString.c_str ());
603686 if (!ok) return false ;
604687
605- scratchString.printf (" C%.4f:%.4f:%.4f:%.4f\n " , (double )torqueConstants[A_AXIS], (double )torqueConstants[B_AXIS], (double )torqueConstants[C_AXIS], (double )torqueConstants[D_AXIS]);
688+ scratchString.printf (" C%.4f" , (double )torqueConstants[0 ]);
689+ for (size_t i = 1 ; i < HANGPRINTER_AXES; ++i)
690+ {
691+ scratchString.catf (" :%.4f" , (double )torqueConstants[i]);
692+ }
606693 ok = f->Write (scratchString.c_str ());
607694
608695 return ok;
@@ -708,10 +795,12 @@ void HangprinterKinematics::ForwardTransform(float const a, float const b, float
708795// Print all the parameters for debugging
709796void HangprinterKinematics::PrintParameters (const StringRef& reply) const noexcept
710797{
711- reply.printf (" Anchor coordinates (%.2f,%.2f,%.2f) (%.2f,%.2f,%.2f) (%.2f,%.2f,%.2f)\n " ,
712- (double )anchors[A_AXIS][X_AXIS], (double )anchors[A_AXIS][Y_AXIS], (double )anchors[A_AXIS][Z_AXIS],
713- (double )anchors[B_AXIS][X_AXIS], (double )anchors[B_AXIS][Y_AXIS], (double )anchors[B_AXIS][Z_AXIS],
714- (double )anchors[C_AXIS][X_AXIS], (double )anchors[C_AXIS][Y_AXIS], (double )anchors[C_AXIS][Z_AXIS]);
798+ reply.printf (" Anchor coordinates" );
799+ for (size_t i = 0 ; i < HANGPRINTER_AXES; ++i)
800+ {
801+ reply.catf (" (%.2f,%.2f,%.2f)" , (double )anchors[i][X_AXIS], (double )anchors[i][Y_AXIS], (double )anchors[i][Z_AXIS]);
802+ }
803+ reply.cat (" \n " );
715804}
716805
717806#if DUAL_CAN
0 commit comments