A new, smaller version of The Spice Must Flow with servomotors: Arrakis

Stripper dust…

3 Likes

dual_speedify is working well, but I’ve got a new idea for a post-processor for the pattern files also related to the speed of drawing/edge motion. I’m going to write a program to read through the pattern file and apply speed that is proportional to the length of the segment being drawn. That way short segments that are part of detailed patterns will be drawn slowly, preserving details, and longer segments (such as along the edges of the drawings) will be drawn at a high speed.

Some patterns will have long segments that are close together so some detail may be lost there, covered by thrown sand, but a lot of the most interesting patterns seem to be made up of many short segments, especially patterns with a lot of curves.

The program will read lines in pairs, calculate the segment length, and multiply it by the maximum speed / the diagonal measure of the table. That will yield a speed proportional to the segment length and will be appended to the second of the two lines that were read.

I may have to experiment with acceleration and jerk settings in the controller once I have the new post-processor working.

Time to review Perl again…

2 Likes

Well alrighty then! First cut at variable speed is working fine. I enter pattern file name, maximum speed, and home coordinates and the program var_speedify.pl steps through the file and appends speed values to each G01 line, with the speed being proportional to the segment length. Only problem is that for patterns with very short segments (curves) the speed can actually hit zero or very close to it. The result is very slow drawing but well preserved detail.

I think I’m going to also input minimum speed so that any calculated value that falls below that speed will simply be replaced by the minimum value. That should prevent the slow crawling that occurs on very curvy patterns.

I’ll post a couple videos of the results tonight.

2 Likes

Your essentially saying, “every segment will take X seconds” now. Assuming you’re coding actually proportional speed.

1 Like

I hadn’t thought about it that way, but it sounds about right.

I calculate the proportional speed this way:
segment length (mm)* maximum speed (mm/min) / diagonal measure (mm)

I’ve modified the program to accept a minimum drawing speed input, so now if the proportional speed for a segment is less than the user specified minimum, that specified minimum speed will be used instead.

I also added a calculation that tells the approximate drawing time required, though controller acceleration and jerk settings will cause it to be a bit different than the calculated value.

Could you just set your acceleration really low and accomplish the same thing?

A good point. I’m not sure it’s the same thing. Acceleration is usually set in the controller and would apply to all pattern files. If you set it really low and you want a pattern to go fast, it might not be able to. For example, I like to run erase patterns really fast, and throwing the sand around helps smooth out the surface when it runs. I want drawings to have fast edge motion and sometimes fast and sometimes not so fast drawing speed.

Arrakis uses a Duet controller that can set acceleration via gcode, so I guess I could just put an M204 statement at the start of each pattern file, but then the problem would be slowing to a crawl when segments are very short.

In the latest version of the variable speed program I set a minimum speed that ensures it never crawls. I don’t think you could do something like that with an acceleration setting alone.

I have done a few more experiments with patterns and remembered something I hadn’t considered.

When I built The Spice Must Flow, I was testing the mechanism right after I installed servomotors, without the sandbox. I put a blue LED in the magnet carriage and then shot long exposures of the machine drawing patterns. IRIC, the drawing speed was something like 1500 mm/sec with maybe 10k acceleration, and the patterns finished in under 2 minutes. I photographed the mechanism in the dark with long exposures, capturing the entire pattern in one image each. Example:

If you look at the photo above, you’ll notice the corners in lines in the drawing look brighter than the centers of the same lines. If you use the variable speed post processor on the files you can control the relative brightness of long and short segments. If you made long segments fast and short segments slow, the slow ones would look brighter than the long, fast segments, and corners would still be bright, too. You could even bin the segment speeds to discrete values and create striped patterns of brightness overlaid on the drawing. Hmm. And maybe use an RGB LED and control its color based on the segment length. Or maybe strobe the LED in proportion to segment length. Hmmm. Or use the LED to light up a luminescent surface, “recording” the pattern for a few minutes before it fades. Maybe the next project… Anyway, variable something based on segment length could create interesting effects.

7 Likes

Oh that is so nice! It looks like a render. I think you might have started a new long exposure trend with that pic!

There are a couple more of those pictures here.

Since a LED is just a point of light, it should be possible to make all sorts of extremely dense, detailed patterns, much more so than with a ball in sand. Since the images have to be viewed on a screen of some sort, the question then becomes: why use a mechanism at all? Why not just apply the colors, brightness variations, etc. in the computer as it generates the pattern?

I have generated and run a few more patterns with the variable speed operation and I’m not impressed. The dual speed program provides an immediately visible improvement in every pattern that has edge motion. The variable speed program doesn’t do much in comparison. You can see the ball running at different speeds when it goes from a long to a short segment and vice -versa, but it doesn’t really have much effect on the details captured in the drawing. It might be great for light painting (or even painting with an airbrush) but it doesn’t really do much in sand. I guess that with sand drawing, below the speed that throws the sand, speed doesn’t matter much. The ball can pass a point at 5 mm/sec or it can pass the same point at 200mm/sec and the drawing will look the same. A camera will register a brightness change as will an airbrush that is spraying paint.

2 Likes

I wonder if you could reduce the speed near “congested” areas of the drawing. You would need to simulate the drawing first to get a complete map of the finished drawing. I would probably use a map made from discrete cells and count the number of times line wen through the cells. Then break the lines into smaller segments and for each segment, add up all of the intersections from nearby cells. If a segment has a lot of nearby traffic, slow it down. If not, let it rip.

That’s an interesting idea. I’ll have to think about how to do that. I’m pretty weak in PERL (and every other language) and it will take a lot of study.

I had another thought. Right now I’m setting the minimum speed at some threshold value and calculating segment speed proportional to the maximum speed over the longest possible segment. The result is that most segments in most patterns end up running at the minimum speed setting. I may as well use dual_speedify.

I’ve been thinking I could flip the logic over and go the other way- set segment speed proportional to the minimum speed on some minimum segment length. Just have the user enter a segment length at which the minimum speed applies, say 10mm. Every segment between 0 and 10 mm gets set to the user input minimum speed, and any calculated speed greater than the maximum value gets set to the user input maximum. Everything in between is proportional to the minimum speed on a 10 mm segment. A 45 mm segment should run at 4.5x the speed of the 10mm segment, etc. If the user sets the minimum speed at 10 mm/sec and the maximum speed at 1500 mm/sec, it would take a segment 1.5 meters long to reach the maximum speed. My table is smaller than that so that maximum speed will never be hit. All speeds will be proportional to the minimum speed over a 10 mm segment length (except segments under 10mm which will be set to minimum speed). Corner to corner edge motion would still be zippy and short segments could be set to run at a very low speed.

I think I’ll try to make this one happen.

That was about a 10 minute job. Now it is behaving more like I was expecting from the start, though the effect is much more subtle than dual_speedify.

Here’s the pattern:

Video here…

As it runs you can see it speed up a bit on the longer segments and slow down for the shorter ones. I probably have the minimum speed set a little low (20 mm/sec). I think what is needed is to set the speed just below the point where the ball gets wobbly, maybe closer to 50 or even 100 mm/sec.

Here is the program, var_speedify_2.pl.

Here is a pattern file.

Here is a sample output file.

Here’s how you run it:

C:\Users\markr\Downloads>perl -w var_speedify_2.pl

Warning- there’s no error trapping, so be careful when you answer
the questions that will follow. Use at your own risk!

Type the name of the sandify pattern file:
220713_01.gcode
Type the maximum drawing speed in mm/sec
1500
Type the minimum drawing speed in mm/sec
20
Type the segment length where minimum speed applies
15
Enter the home position X ordinate.
590
Enter the home position Y ordinate.
0

Processing is complete.

The variable speed output file is called 220713_01_varspd.gcode

The total time required to draw the pattern is approximately 76.07 minutes.

Check the output file to make sure it does what you think it will.

2 Likes

I know what I know. I don’t know perl, but I would allocate a two dimension array. For each line segment, you need to trace from start to end, and each cell the line “visits” needs to be incremented. You need to have a reliable method for converting from X,Y to the 2d array.

Then you would have a record of which cells had how many visits.

You have to precompute that for a whole pattern and then go through the list again. You need to again ray trace through the cells and at each cell, determine the amount of detail around you. You can either just look at that exact cell, or also check the “nearest neighbors” (adding one to the col, and then row, etc. A configurable amount of cells away). Then you have some number for the amount of detail in that cell. You can choose to accumulate those for a line, or choose the max detail from any cell for a line and use that to compute the desired speed for the line.

You would learn about making a 2D map, and 2D ray tracing. Both of those skills are very useful in ground robotics. I use these every day. I think it is useful. But I am biased :slight_smile:

Your new solution sounds good too. And it looks like it is working. I think where my solution might work better is patterns with huge straight lines in a tight pattern.

I’ve been experimenting with the new variable speed program. One of the things I included in it is a calculation of the time required to draw the pattern being processed. I have run a couple patterns that take over an hour to draw and found that the calculated time is accurate to within a minute. The table is currently running at acceleration of 10k mm/sec^2 and jerk speed set to 100 mm/sec. I imagine that if the jerk and/or acceleration is set lower, the accuracy will get worse, with the pattern taking longer than the calculated time.