James Newton

362 followers -

Technical Education, The Scientific Method, Wearable computing, Electronics, Kits, 3D printing, CNC, Stepper Motors and Controllers.

Technical Education, The Scientific Method, Wearable computing, Electronics, Kits, 3D printing, CNC, Stepper Motors and Controllers.

362 followers

Communities and Collections

Posts

Need to duplicate an existing object. The standard JSON.Stringify / parse thing doesn't seem to be working... any ideas?

var washer = circle({r:(params.hub/2+0.8), center: true})

.subtract(circle({r:params.hub/2, h:2, center: true}));

var washer2 = JSON.parse(JSON.stringify(washer));

"TypeError: s.extrude is not a function"

var washer = circle({r:(params.hub/2+0.8), center: true})

.subtract(circle({r:params.hub/2, h:2, center: true}));

var washer2 = JSON.parse(JSON.stringify(washer));

"TypeError: s.extrude is not a function"

Any way to place objects according to the width of the prior object? E.g. If you want to lasercut a lot of parts, it would be great to be able to place them side by side, accumulating the width of the prior part.

I'm assuming there is no way to get the size of a 2d part from the object itself, but if you know the size you defined the object as, then you can translate the object by that amount in the new collection.

So if you define an object, of some size, then you can add an attribute with that size to it. E.g. var base = square({size: [10,10]}); base.w = 10; base.h = 10;

Then a new method like "object.right(object).right(object)" which does a translation of each prior object to the left, by the .w value of the object. Or something like that.

But I figure someone has done that already, or has a better idea than I do.

I'm assuming there is no way to get the size of a 2d part from the object itself, but if you know the size you defined the object as, then you can translate the object by that amount in the new collection.

So if you define an object, of some size, then you can add an attribute with that size to it. E.g. var base = square({size: [10,10]}); base.w = 10; base.h = 10;

Then a new method like "object.right(object).right(object)" which does a translation of each prior object to the left, by the .w value of the object. Or something like that.

But I figure someone has done that already, or has a better idea than I do.

Apparently 2D objects can have color? It would be nice to be able to set the line color or line width for output to laser cutters. Full spectrum keys cut speed / power on color and Epilog uses line width.

Ok, the web page at openjscad.org very clearly says that it can export SVG files. However, there is no option to do so in the lower left pull down. No mention of it in the documentation (that I can find) and google doesn't seem to know how to do it except from the command line. Is it not possible from the web page?

I would very much like to be able to burn a disk after writing this:

https://openjscad.org/#https://gist.githubusercontent.com/JamesNewton/c8598878736442c440bbe41d086291ac/raw/20ece2cea1586e18f0b5236edfc8b89ddf05ede0/encoderdisk.jscad

I would very much like to be able to burn a disk after writing this:

https://openjscad.org/#https://gist.githubusercontent.com/JamesNewton/c8598878736442c440bbe41d086291ac/raw/20ece2cea1586e18f0b5236edfc8b89ddf05ede0/encoderdisk.jscad

This does not work, throwing a error: "TypeError: a[i].setColor is not a function"

function getParameterDefinitions() {

return [

{ name: 'disk', type: 'float', initial: 77, caption: "diameter of the disk:" },

{ name: 'hub', type: 'float', initial: 2, caption: "diameter of the hub:" },

{ name: 'slots', type: 'float', initial: 157, caption: "number of slots:" },

{ name: 'slotlength', type: 'float', initial: 3.5, caption: "length of each slot:" },

{ name: 'cutfudge', type: 'float', initial: 0.4, caption: "width of laser cut / negative spread of printer filament:" },

];

}

function main () {

var slotwidth = Math.PI*params.disk/params.slots/2 - params.cutfudge;

var cubes = [];

cubes[0]=cube({size: [params.slotlength,slotwidth, 2]});

var output = union(

difference(

cylinder({r: params.disk/2})

,cylinder({r: params.hub/2, h:2, center: true})

,cube({size: [params.slotlength,slotwidth, 2]})

,cubes

)

).translate([0, 0, 0]).scale(1);

return output;

}

If you comment out the line ",cubes" it works. If you change the return to return cubes /that/ works. Why can't you difference an array? Or rather, how would you punch out a bunch of cubes from the disk?

function getParameterDefinitions() {

return [

{ name: 'disk', type: 'float', initial: 77, caption: "diameter of the disk:" },

{ name: 'hub', type: 'float', initial: 2, caption: "diameter of the hub:" },

{ name: 'slots', type: 'float', initial: 157, caption: "number of slots:" },

{ name: 'slotlength', type: 'float', initial: 3.5, caption: "length of each slot:" },

{ name: 'cutfudge', type: 'float', initial: 0.4, caption: "width of laser cut / negative spread of printer filament:" },

];

}

function main () {

var slotwidth = Math.PI*params.disk/params.slots/2 - params.cutfudge;

var cubes = [];

cubes[0]=cube({size: [params.slotlength,slotwidth, 2]});

var output = union(

difference(

cylinder({r: params.disk/2})

,cylinder({r: params.hub/2, h:2, center: true})

,cube({size: [params.slotlength,slotwidth, 2]})

,cubes

)

).translate([0, 0, 0]).scale(1);

return output;

}

If you comment out the line ",cubes" it works. If you change the return to return cubes /that/ works. Why can't you difference an array? Or rather, how would you punch out a bunch of cubes from the disk?

Is there a way to stack objects on top of each other? E.g. rather than translating an object up by the height of another object, make the second object the child of the first and specify that it should be offset up by the height of the parent object.

Post has attachment

Public

Tired of tending your print jobs? Video

https://www.youtube.com/watch?v=g7vwe5gVP3k

Mantis gripper was adapted to Dexter open source robot arm from +Haddington Dynamics to remove parts from a 3D printer. And there is no reason why the arm couldn't be programmed to assemble the parts, if they came off the printer clean enough.

http://www.appropedia.org/User:Zsarnold#Enterprise See "Semester 2"

Mantis Gripper Design

https://www.thingiverse.com/thing:1480408

and Dexter adapter files

https://www.thingiverse.com/thing:2877079

Code

https://pastebin.com/EKfpEdBR

Images:

https://imgur.com/a/42GDrtg

https://www.youtube.com/watch?v=g7vwe5gVP3k

Mantis gripper was adapted to Dexter open source robot arm from +Haddington Dynamics to remove parts from a 3D printer. And there is no reason why the arm couldn't be programmed to assemble the parts, if they came off the printer clean enough.

http://www.appropedia.org/User:Zsarnold#Enterprise See "Semester 2"

Mantis Gripper Design

https://www.thingiverse.com/thing:1480408

and Dexter adapter files

https://www.thingiverse.com/thing:2877079

Code

https://pastebin.com/EKfpEdBR

Images:

https://imgur.com/a/42GDrtg

Add a comment...

Post has attachment

Public

Well, this is cool... you can program /and debug/ (!) in the browser.

https://onlinegdb.com/ByHX30JOf

https://onlinegdb.com/ByHX30JOf

Add a comment...

Post has attachment

Public

Adding acceleration to the movements makes a huge difference, now we don't have to stand on it to keep it from flipping over. In fact, its own weight is enough to keep it flat while lifting an arm and weight. That is about 8 lbs at a foot and a half, so basically nothing compared to the capacity of the unit.

Just like an RC servo, but 1 foot square, 5000 oz/in, can run from power tool batteries, and the wifi / web interface allows control from your cell phone. Electronics are currently available for about $50 and the box will probably be $250 fully assembled.

#MassMindMonster

Just like an RC servo, but 1 foot square, 5000 oz/in, can run from power tool batteries, and the wifi / web interface allows control from your cell phone. Electronics are currently available for about $50 and the box will probably be $250 fully assembled.

#MassMindMonster

Add a comment...

Public

So... Motion Control Time. You have a thing that is still, then moves with acceleration A. A is a constant. Each time tick T, A is added to V and V is added to P. V being velocity and P being position. Note that this is not continuous... that's a key point.

And there is a maximum velocity, Vmax and when all that adding of A to V gets above Vmax, we stop doing that... from then on, we just add V to P each time tick and don't add anything to V. In other words, we stop accelerating when we reach maximum velocity.

Now, the trick is that we have some final goal position, G, and every time we move P we are subtracting from G until it is 0 and we are there. But that doesn't work, because you can't stop instantly. You need to decelerate at the end. But how far from the end should you start that deceleration?

Well, we will decelerate at the same rate A, by just subtracting A from V until we come to a stop. But the question is, how far from the goal do we start doing this? Well, we know how long it took to accelerate, so it will be the same distance. But what if the max velocity or goal position changes during the move? Or what if we didn't have time to fully accelerate to max velocity?

Well, V is the derivative of P and A the derivative of V. Or, the other way around, V = A*T (c = 0 'cause we are at rest when we start) and P = 1/2*A*T^2 (again, no c). And since Vm = A*Tm (Vm and Tm being the velocity and time at which we reach max velocity) we can solve for Tm = Vm/A and substitute that into Pm = 1/2 * A * Tm^2 to get Pm = 1/2 * A * (Vm / A)^2 = Vm^2 / (2*A). BTW, this paragraph was brought to you by my son, Remy... I couldn't remember how to do integrals.

And then you can make a spreadsheet and put in values and test that equation and find that the values, while generally close for a while, do NOT match. Why? Because the equation is a continuous function and the method above is a step function. It recalculates new values only once every time tick, not all the time.

So... the only way I know to calculate that distance from the goal is to do a loop and add up V and track P until V reaches Vmax.

Know any better ways?

And there is a maximum velocity, Vmax and when all that adding of A to V gets above Vmax, we stop doing that... from then on, we just add V to P each time tick and don't add anything to V. In other words, we stop accelerating when we reach maximum velocity.

Now, the trick is that we have some final goal position, G, and every time we move P we are subtracting from G until it is 0 and we are there. But that doesn't work, because you can't stop instantly. You need to decelerate at the end. But how far from the end should you start that deceleration?

Well, we will decelerate at the same rate A, by just subtracting A from V until we come to a stop. But the question is, how far from the goal do we start doing this? Well, we know how long it took to accelerate, so it will be the same distance. But what if the max velocity or goal position changes during the move? Or what if we didn't have time to fully accelerate to max velocity?

Well, V is the derivative of P and A the derivative of V. Or, the other way around, V = A*T (c = 0 'cause we are at rest when we start) and P = 1/2*A*T^2 (again, no c). And since Vm = A*Tm (Vm and Tm being the velocity and time at which we reach max velocity) we can solve for Tm = Vm/A and substitute that into Pm = 1/2 * A * Tm^2 to get Pm = 1/2 * A * (Vm / A)^2 = Vm^2 / (2*A). BTW, this paragraph was brought to you by my son, Remy... I couldn't remember how to do integrals.

And then you can make a spreadsheet and put in values and test that equation and find that the values, while generally close for a while, do NOT match. Why? Because the equation is a continuous function and the method above is a step function. It recalculates new values only once every time tick, not all the time.

So... the only way I know to calculate that distance from the goal is to do a loop and add up V and track P until V reaches Vmax.

Know any better ways?

Add a comment...

Wait while more posts are being loaded