Modeling rotating hanging bead chains

Hi all,
I’m a motion control artist and a big fan of Grasshopper (which I use to create algorithmic 2D paths for my sand plotters). I’ve recently fallen in love with “bead chain” - the stuff hanging from closet lights and used to pull up blinds. The way it moves can be very beautiful. Lately, I’m spending a lot of time with a prototype I call “dervish”. I’m intrigued by how complex, yet reproducible behavior such a simple, single-actuator system can display. At present, the process of finding motion profiles that produce stable and aesthetically pleasing results is completely trial and error - and because of the inertia of the chains, “resetting” between trials can be very time consuming (especially as the piece scales). My hope is that modeling the kinetics might offer some insights. I was delighted to discover Kangaroo, and amazed that one of the first tutorials I found looked just like bead chain! Here is my tweak of it:


beadchain1.gh (14.6 KB)

I’ve tried to find examples that would allow me to rotate a hanging chain around an axis (I suspect a tether-ball example could help as well), but haven’t yet found anything. I’m hoping someone might be able to point me in the right direction.

2 Likes

These are really nice sculptures. They remind me of kinetic wind sculptures and work by artists such as Ivan Black

I’ve often wondered about how to use Kangaroo to design similar things.

I’m sure it should be possible to use Kangaroo to simulate your bead chains… there is a component called Grab in Kangaroo that lets you grab a particle and drag it so I assume it should be possible to apply the motion of an actuator to a particle at one end of the bead chain.

I would try and define how that actuator input is best described in a way that would allow you to easily replicate in a real world model. i.e. what control over the actuators do you have? do they just rotate back and forth over a pre-set angle in a pre-determined time? Can you effect accelleration and decelleration?

Also, you might need the Kangaroo physics engineering version to give your bead chain realistic material properties.

Then I would hope that @DanielPiker sees this and can offer some help!

Perhaps it would be possible to have a custom Grab component called Actuator (Linear and rotational) that would allow you to apply a specific motion to a particle?

Interesting sculptures!

twizzler.gh (29.3 KB)
Here’s a go at this.
The basics are fairly simple to set up - cables resisting change in length, gravity, moving anchors at the top, and collision between the chains.
Really accurately matching the dynamics of the real system could be tricky, as there are a lot of subtle factors at play, but hopefully this is a start.

15 Likes

Here’s a little extension script that lets you define a spline as a path as well twizzler_spline.gh (13.5 KB) It assumes a closed spline.

4 Likes

What makes the anchors move?
Would it be possible to give them other movements other than just rotating in one direction? i.e. oscilating back and forth?

Sure…the little custom script is basically a counter. You can feed it into any function that would cause it to oscillate:

1 Like

Anchors take as input a point P which identifies the point to be moved, and another point T giving the location to move it to.
You can update the location of T however you like with the the part of your Grasshopper definition upstream of Kangaroo(including with a timer or a slider) while Kangaroo is running, and the anchor will move to the new location.
Note that moving P instead during simulation would mean the anchor would become disconnected from the geometry it was supposed to fix.

1 Like

Full motion control - position, velocity, and acceleration. “Choreography” consists of finding simple profiles, like go a distance at a target velocity, ramping up and down with given accelerations, and then linking profiles in a “playlist” (which generally repeats). Though there’s only one actuator, the possibilities are endless, especially when connected to the messy real world :slight_smile:. Thanks for kind words and the link to Ivan’s work - it’s fantastic!

HOLY CRAP - I’m simply blown away! Thanks so much!! I know I have a long ways to go before I even remotely grasp what’s going on, and the limitations of accurately modeling real world objects like bead chain - but the speed with which you created and shared this is amazing. I’m new to Kangaroo, and have only limited experience with Grasshopper, but I’m looking forward to diving in. I haven’t been able to leave my computer all day since I started messing with it:

17 Likes

There’s a plugin for Grasshopper that lets you connect to devices called FIREFLY

It would be cool to see the real thing move alongside the Kangaroo simulation all from the same slider!

Thanks for that suggestion! I am very comfortable with Arduino for control of both LEDs and actuators. It would indeed be cool to see real and simulation from the same slider.

Now that I’ve played with your routine a bit, I’m starting to get a “feel” for the parameters of the Bouncy Solver and Collider. And I think, given your C# script, as well as @dave_stasiuk’s example, I could devise a scheme to stream in a list of anchor moves (but still on the circle) that would emulate my “profile playlist” strategy with the real prototype. But one thing seems to be missing - i.e. a centripetal acceleration factor. While the simulated strand behavior looks remarkably like the real thing, it does not splay with increasing angular velocity like real strands do. Since centripetal accel is independent of mass (like gravity), I think I need an accel that always points to the center of rotation, proportional to the radius of the rotating point and the square of the angular velocity. Could Vortex or Spin Force work for this?

Since you posted your example, I’ve been spending more time with Kangaroo than my “real” work :face_with_raised_eyebrow:. What spurs me on is the uncanny resemblance of the simulation to the real thing:

vs. Dervish prototype with 5m bead chains (from below).

I’ve tried multiple ways to add centripetal force to the simulation - alas without success. While I know that a sim will never be exact for something as messy as whirling chains, I think this missing component might make a big difference in my being able to glean types of interesting choreography more rapidly than my current trial and error methods with prototypes. Here is my very crude model of the centripetal effect, showing the chain angle from vertical increasing with rotational speed:


BScentripital.gh (19.2 KB)
The name is apt in that actual speed vs. angle-from-vertical relation is not linear as in my sketch - (it’s proportional to arctan(angular velocity squared * length of chain). I tried numerous ways to figure out how to feed this relationship of Theta (angle from vertical) as a goal for the solver, but to no avail. Here’s my latest “combined” attempt: DPtwizzleandBScentripital1.gh (32.2 KB)

Though frustrating at times, this “exercise” has helped improve my familiarity with both GH and Kangaroo. I’m not sure if my goal is achievable with the current components available - but if you or others have suggestions, I’d be very grateful for pointing me in the right direction (C# is not the language I use for my motion control coding, but I have written GH scripts using it before).

Deep thanks to you, both for your initial example and your amazing plugin!

Bruce

5 Likes

Hi @Bruce_Shapiro,
Sorry I didn’t reply to your last post yet - I started writing something earlier, but it’s tricky to describe without going into a bit more detail about the way the Kangaroo solver works.
First off - there’s definitely no need to add any special goals or calculations for centripetal or centrifugal forces. One great thing about simulating physics is that many more complex phenomena emerge naturally without more coding needed once the basics are set up right. In the case of centripetal force, it’s just the result of the momentum and tension of the chain.
The reason for the difference in behaviour between the simulated and real world behaviour will have more to do with the damping.
A solver like the one in Kangaroo needs a method for stepping through time, and ideally the algorithm for this should have several properties:

  1. Stability - it should not explode when high stiffness materials are used.
  2. Numerically accurate deformations - it should be possible to control precisely how strongly each of the goals are enforced relative to each other in the final result, particularly if we want to use it for structural analysis.
  3. Fast convergence to the equilibrium solution. For form-finding applications, we are mainly interested in reaching the final static form, and should be able to get there without needing millions of tiny time steps, or waiting for it to bounce around for a long time.
  4. Energy preservation control. If we want to simulate accurate dynamic behaviour, it is good to be able to control how much energy gets converted from kinetic to heat with each step.

In the first versions of Kangaroo, items 1-3 were often problematic - if you wanted to use high stiffness materials, it often required impractically small time steps to avoid making the whole simulation explode, meaning it would take forever to converge.
The new mathematical method I used for Kangaroo2 largely solved these issues, but at some cost to item 4. The new solver can use much bigger steps, even with extremely high stiffness materials, without exploding, which is great for example if you want to see how much a loaded steel truss deforms with real numbers for Young’s modulus and weight of the material, or enforce strict planarity in a panelisation, or quickly find a minimal surface for a given boundary.

However, it does tend to remove a small amount of energy from one frame to the next. Note that this is separate from the actual damping input setting - that gives you the option to add more damping, but there is always some level which is inherent to the time stepping method used, and it is currently not possible to reduce this to zero.
For form-finding (which is the primary purpose of Kangaroo), damping is actually good - we want to quickly get rid of all the kinetic energy so we can find a stable minimum of the total potential energy. What we definitely never want is simulations that artificially gain energy out of nowhere.

Of course in the real world total energy is conserved, but when simulating things happening on earth, in air, there is always some amount of damping, both from the internal friction of elastic materials and from air resistance, and for some dynamic applications where the inherent solver damping is close to or lower than this we can get a good approximation of the behaviour, adding even more damping if necessary.

For something like this relatively stiff, elastic, dense, and thin chain of your sculptures though, the real natural energy losses are probably quite a bit lower than the inherent damping of the currently available solver options.
One other example of something which is not really possible to do so well in Kangaroo2 is orbital simulation of planetary systems. The old solver was really good at this because it used a symplectic integration method. This was a fairly tangential and rarely used application though, so I’d considered it an acceptable sacrifice.

I have been working on ways of improving the solver methods to try and get the best of both - ideally Kangaroo would include options allowing you to precisely control damping, with the possibility to take it all the way down to exactly zero (with separate numerical controls for internal elastic friction and air resistance), while still always remaining stable, still with the option of making materials arbitrarily stiff, or even absolute constraints, and still giving numerically accurate deformations, all while keeping the goal interface simple (so custom goals can still be created just with target positions and weights, without having to mess about with Hessians and higher derivatives). This is all easier said than done though! Even cutting edge simulation research always seems to fall down on at least one of these. It may end up that multiple solver options are needed with different trade-offs, but I’d like to avoid making things too complicated.

So… perhaps more information than really needed! and I realise it doesn’t give a solution to the immediate issue, but hopefully at least gives a bit of insight.

8 Likes

What’s the ultimate goal of this project, to see the pattern from the underside, where the chains are mounted in the ceiling?

I started trying to add a centripetal force and you can create a vector Load goal using Vector2pt from the central axis of rotation to each point on the chain but you can only give it a static amplitude. I don’t think you can change the load according to what is happening in the solver. What you need to do is set that Load amplitude to be, as you say, proportional to angular velocity.

After reading through what Daniel said, tweak the damping setting… maybe use a slider with 4 digit resolution.

twizzler.gh (15.8 KB)

Just to be clear - adding a special ‘centripetal force’ will not help here.
It’s just a way of looking at the force stopping the chain from flying away from the centre, which in this case is provided by the tension in the chain (the length goal). The force is already there, there’s no need to add anything extra.
I’m afraid higher resolution for the damping value isn’t going to help much here either. Even with zero added damping, the solver is still removing more energy from the system than we want here.

One idea for another possible way to tweak this.
When using the bouncy solver, there is essentially another goal included inside the solver for each particle which tries to move it to where it would end up if it kept the same velocity it had in the previous step (i.e. inertia). There isn’t currently an explicit user control for the strength of this goal - it defaults to 1.0 for all particles. However, since it is only the weights of the goals relative to each other that actually matters, decreasing the weights of all the other goals has the effect of increasing this inertia, so the motion of the particles is damped less.

twizzler2.gh (12.0 KB)

1 Like

I just meant give it a higher resolution (i.e. 4 digits instead of 3) so it can be changed in smaller increments. It did seem to be sensitive and make a difference so I wondered if it could get closer to what Bruce was aiming for.

It will be interesting to see how close he can get it by tweaking the inertia as you describe plus the damping, load value etc.

Hi @DanielPiker,
No need to apologize! Had you immediately replied with yet another great example, I’d never have spent so much time with Kangaroo (and at the same time, added to my Grasshopper skills). You have again blown me away - not only with your second, “improved” routine, but with your very thorough explanation of how Kangaroo works, including the difference between 1 and 2, and the strategies driving them. While I am comfortable with math basics enough to be a reasonable spectator when you refer to “Hessians” and “symplectic integration” (thank you, Wikipedia), the meat of your explanation, with respect to my grasping it, is your very understandable prose related to how the solver works, and why/how damping is so key. And most important (for me) - why centripetal/centrifugal force is already contained within the dynamic model.

I have just begun to play with your “twizzler2.gh”, and already the stuff I’m able to produce makes the hairs on the back of my neck stand up! It’s hard to describe my feelings, after spending so much time watching twirling 16’ strands of steel bead chain twining and splaying and dancing, while trying to tease out some reproducible choreography - all the while cursing their inertia (which of course is why their movements are so interesting) - when I see identical types of movements in the simulations you’ve enabled me to view on my Rhino screen. It’s going to take me a while - real world stuff to attend to and all - but I intend to share videos that demonstrate just how close your simulation is to the real thing. It may be a feeble expression of the gratitude I owe you - but I will do my best. Again - deep thanks!