Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login
    1. Home
    2. leone
    3. Best
    • Profile
    • Following 2
    • Followers 2
    • Topics 9
    • Posts 39
    • Best 6
    • Controversial 0
    • Groups 0

    Best posts made by leone

    • [3.6.0-beta.2 and prev] Random out of sync

      Hi all,

      from 3.6.0-beta.1 I started to have some layer shifts in the first layers of a print. These shifts happen randomly (the same gcode might shift in one print and not in the consecutive one, or just in another position). Still, I didn't find a way to replicate exactly the issue. The shift happens because the expansion boards go out of sync for about 2 seconds and the movement commands are discarded (as intended behavior from 3.6.0-beta.1).
      So far, it never shifted when the bed compensation was disabled or, when enabled, it never shifted above the tapering height (5mm).
      To debug, I connected a can sniffer device and analyzed the TimeSync messages. The out-of-sync happens when the field lastTimeAcknowledgeDelay is zero for more than 10 consecutive times. From my understanding, the CanClockLoop doesn't update this variable if the previous message takes more than MaxTimeSyncDelay between the call of the send function and when the ISR actually processed the TX callback.

      352vs360.png

      From the plots you can see that the behavior of lastTimeAcknowledgeDelay with FW 3.5.2 and 3.6.0-beta.1 is similar, so I might never have had a shift before just because in 3.5.2 the movement commands weren't discarded.
      I increased MaxTimeSyncDelay from 300 (400 usec?) to 375 (500 usec?) to see what happens: these spikes are still present but the number of zeros is reduced, so hopefully tolerant enough to never reach 10 consecutive samples.

      360_inc_thr.png

      360_inc_thr_zoom.png

      From the plot, it looks like the normal value for lastTimeAcknowledgeDelay is around 3-5 and a cloudy distribution around 250-300. So the original threshold of 300 would make sense.
      I'm wondering why there are these spikes, after one spike to about 300 or more, the spike is then repeated every 5 samples but with a linear decreasing amplitude.
      I tried also to disable the input shaping but the overall distribution is similar.

      Do you have any explanation for this behavior? Other processes or interrupts interfering? Do you think it would make sense to increase the MaxTimeSyncDelay threshold or is it just a patch? Do you foresee any issues arising from doing this?

      Thanks in advance.

      posted in Beta Firmware
      leoneundefined
      leone
    • [FW 3.5.2] High jerk good for circular path not for corners

      Hi all,
      I am doing some motion tuning for a quite big and heavy machine. In general I noticed that having high values of jerk (about 500-600 mm/min) are good enough to travel circular paths smoothly (even tough it depends a lot on the mesh quality), but they are a bit high when printing corners, reducing a lot the effect of the input shaping and introducing lot of ringing.
      Since I couldn't find a decent balance of jerks, acceleration and the Input Shaping L parameter, I modified a bit the function DDA::MatchSpeed and the command M566:

      Basically my idea is to estimate the angle between two consecutive segments and if it is greater than a certain threshold I use a lower value of jerk.

      a (3).jpg

      I added to M566 a parameter J "junctionDeviation" which is the threshold below which an high value of jerk is used (the one set from M566 X-- Y--). For greater values, the minimum jerk multiplied by the parameter S is used.
      I consider as threshold the difference between the X components of v1 and v2 in the reference frame of v1, and since v1 and v2 are unit vectors the threshold is equal to (1 - cos(alpha)).

      void DDA::MatchSpeeds() noexcept
      {
      	// v2 needs to be expressed in the reference frame of v1
      	// directionVector and next->directionVector are unit vectors
      
      	// The rotation matrix R(-alpha) can be expressed by using the directionVector[0] and directionVector[1] which are the X and Y components of v1 in the absolute reference frame (v1_0).
      	const float rotationMatrix[2][2] = {
      		{ directionVector[0], directionVector[1] },
      		{ -directionVector[1], directionVector[0] }
      	};
      
      	// Project v2 in the reference frame of v1 (v2_1)
      	const float nextVectorProjected[2] = {
      		rotationMatrix[0][0] * next->directionVector[0] + rotationMatrix[0][1] * next->directionVector[1],
      		rotationMatrix[1][0] * next->directionVector[0] + rotationMatrix[1][1] * next->directionVector[1]
      	};
      
      	// Difference of X and Y components in the reference frame of v1 (v1_1 - v2_1)
      	const float relativeFraction[2] = {
      		fabsf(1 - nextVectorProjected[0]),
      		fabsf(0 - nextVectorProjected[1])
      	};
      
      	for (size_t drive = 0; drive < MaxAxesPlusExtruders; ++drive)
      	{
      		if (directionVector[drive] != 0.0 || next->directionVector[drive] != 0.0)
      		{
      			const float totalFraction = fabsf(directionVector[drive] - next->directionVector[drive]);
      			const float jerk = totalFraction * beforePrepare.targetNextSpeed;
      			float allowedJerk = reprap.GetPlatform().GetInstantDv(drive);
      			// if dealing with X and Y axes reduce jerk if sharp edges
      			if (drive < 2 && relativeFraction[0] > reprap.GetPlatform().JunctionDeviation())
      			{
      				allowedJerk = ConvertSpeedFromMmPerSec(MinimumJerk * reprap.GetPlatform().MinimumJerkMultiplier());
      			}
      			if (jerk > allowedJerk)
      			{
      				beforePrepare.targetNextSpeed = allowedJerk/totalFraction;
      			}
      		}
      	}
      }
      

      Of course the code is not optimised, but it was just a first test to see if the idea could work.
      I have done a couple of prints with a bit extreme setting (M566 X600 Y600 J0.01 S1) and I noticed a good improvement in print quality. Corners don't induce much ringing, so the input shaping can play a role there, and circular motions are done without too much scattering.

      I'd like to have some feedback from this approach, especially if you see weird/dangerous edge cases that I didn't think about, in the code implementation and/or in the machine behaviour.

      Thank you in advance to all of you!

      posted in Tuning and tweaking
      leoneundefined
      leone
    • Collect ADC sensor values at high frequency

      Hi all,

      I'd like to ask your opinion about having the possibility to stream data at high frequency from a generic ADC sensor (connected to an expansion board) to a CSV file (similar to what the M956 is doing with the accelerometer). I have this need because the CAN frequency at which the sensors are updating is too low for some of the custom calibrations I'm doing. I have something working based on the AccelerometerHandle, but I'd like to see if it is of interest to do a proper refactor and open a pull request from that.

      My idea would be to have something like: M956.1 Pbb.nn Snnn F"" (board.pin name, number of samples, filename). The implementation would be similar to how the accelerometer works, so:

      • add two CAN messages, one for the start request and one for the data structure (or somehow use the accelerometer messages?)
      • an AdcStreamHandler: to be initialized from the pin name and have a task to collect the raw data and build/send the CAN messages
      • modify AveragingFilter.h to return all the collected samples (without interfering with the average)
        Side question: I'm not quite sure at which frequency the ADC is updating the filter queue: from a comment "Readings will be taken and about every 'ticksPerCall' milliseconds the callback function will be called with the specified parameter and ADC reading.". It seems like the analog ports are configured with 1, does this mean the adcFilter queue is filling up at 1ms rate?

      BTW, what do you think about this feature? The main goal is to get values at high frequency (buffered, not necessarily in real-time, but with a known time interval between the samples). Do you see other approaches that could be followed to have the same functionality?

      Thank you in advance.

      posted in Firmware developers
      leoneundefined
      leone
    • RE: [3.6.0-beta.2 and prev] Random out of sync

      now I'm doing some tests increasing StepTimer::MinSyncInterval from 2000 to 4000. I noticed it was already increased some years ago, it might be the same issue, I am also running on a SAME70.

      posted in Beta Firmware
      leoneundefined
      leone
    • RE: [FW 3.5.2] High jerk good for circular path not for corners

      @Triet, what @gloomyandy correctly explained is how the jerk is implemented in RRF 3.5.x and also 3.6 betas. The jerk set from the configuration is the max allowable speed change that a specific axis can do between two consecutive moves: RRF checks the components of the direction vector between two consecutive moves to understand how much each axis has to change in speed, if this change is greater than the threshold (jerk), then the threshold itself will be used.

      What I proposed as adaptive jerk meant to change dynamically this threshold, based on a non linear relationship with the direction angle. It's one layer of logic above what RRF is already doing, maybe something like "adaptive MAX jerk" would have been more clear 🙂

      I actually paused this investigation because the results I got with the 3.6 betas and the new input shaping are very good and fixed most of my issues.
      I can confirm that find a reliable logic to implement here is more difficult than it might seems. Maybe in future I'll give another chance to the junction deviation or the "adaptive MAX jerk" on top of 3.6 to see if there are real benefits.

      posted in Tuning and tweaking
      leoneundefined
      leone
    • RE: [3.6.0-beta.2 and prev] Random out of sync

      Thanks @droftarts.
      Update note: I got a resync also with MaxTimeSyncDelay = 375.

      posted in Beta Firmware
      leoneundefined
      leone