This robotic fish was a final project for 2.74, Bio-Inspired Robotics, which I took in Fall 2015. (To my disappointment, we were not permitted to ride Prof. Kim’s cheetah robot in class, but we did get to work with a scaled-down model of the cheetah leg mechanism.)
One of the key principles emphasized in the class is that bio-inspired robots are not designed to replicate actual animals. Instead, they’re used for “principle extraction,” or isolating the mechanical principles underpinning a particular feature of the natural world. Once you’ve isolated the relevant principle — anything from the running gait of a cheetah to the mechanics of hummingbird hovering — and created a model of the system, building a physical robot allows for real-world validation of that model.
For our final project, our teams were instructed to choose an animal behavior, create a dynamic model, and experimentally test some aspect of our model using a physical robot. Among the topics other teams chose were how cats right themselves as they fall, how monkeys swing between branches, and how athletes throw objects; my team was particularly interested in the dynamics of fish swimming.
In still water, fish swim by undulating their bodies to amplify a fluid wave as they move through the water. In turbulent water, however, fish only engage the muscles near their head to control their position, and they don’t move the rest of their body. The fish musculoskeletal system passively responds to turbulence, so they gain a propulsive advantage and swim with minimal energy expenditure. This mechanism is so refined that even a dead fish will “swim” when placed in an artificial current, as shown in the video below:
This is completely counterintuitive and evolutionarily fascinating. It implies that a fish body can be modeled as a flexible object with some defined stiffness, and that the stiffness of the fish’s body will affect how efficient the swimming motion is.
For our project, we chose to study the effects of joint stiffness on the cost of transport of swimming. To simplify the model, we focused on the carangiform gait, a type of fish motion with very little head movement. Anguilliform fish (like eels) and subcarangiform fish (trout and salmon) swim by moving their entire body; this motion makes it difficult to constrain a robot without affecting the hydrodynamics. Thunniform fish (tuna, sharks) only use their tails, but their swimming relies heavily on vortex shedding and is difficult to model. Carangiform fish (trevally, mackerel) gave us a good balance of limited head movement and limited vortex shedding.
We modeled our fish as a system with three links and two joints, with motors actuating the joints so we could easily vary the joint stiffness. Beckett modeled the fish in MATLAB and ran gradient optimizations on the torque amplitude, spring stiffnesses (K1 and K2), and operating frequency. After running extensive simulations on various combinations of spring stiffnesses, he found that the cost of transport was minimized with a low K1 (the stiffness of the front spring) and a high K2 (the stiffness of the back spring).
Once we had a model, it was time to validate it with real-world testing. Jennie set up our motor controllers and feedback system, and I set about building a fish. I picked an island jack as our “representative fish”; keeping the body shape of the robot fish close to that of an actual carangiform fish would help make our results realistic. All of the fish pieces were 3D-printed.
We used a belt system to drive the body and tail links, with the motors mounted safely out of the water on a rigid platform supported by two pontoons. The fish was suspended from a rigid strut, which was tapered to minimize vortex shedding.
To test our fish and collect data, we set up a fixed center platform in a pool. The fish was connected to the platform using a rigid boom, with the motor wires running through the boom and connecting to the microcontroller (in a drybox on top of the platform) via a slip ring. The fish was thus constrained to swim in circles, and we could easily measure the distance it swam. To measure the efficiency of various spring stiffness combinations, we set the spring stiffnesses appropriately and let the fish swim for a fixed length of time. We then recorded the distance it had covered in that time.
Our results were less clean than we would have liked because of issues with our encoder skipping counts (the fish kept smacking its tail into itself, which is not generally an efficient mode of swimming), but we did find that swimming cost of transport was minimized with a spring stiffness ratio (K1/K2) of 0.6. If we decide to take this further, we’d start by resolving the encoder issues, and then would look at the effects of a flexible vs. a rigid tail on the cost of transport.