Approximation And Control - ksoltan/RoboFish GitHub Wiki
You may be wondering why all of the MATLAB functions are needed and what they actually do. The MATLAB code performs three tasks: allows to simulate the posture function best to approximate with joint length configuration, get a discrete approximation, approximate each joint intersection (hinge)'s motion, and get the timing pattern.
Discrete Joint Approximation
The joint approximation algorithm described in Liu and Hu's paper, Biological Inspiration: From Carangiform Fish to Multi-Joint Robotic Fish, is reproduced in the discretize_posture function. Because we are using a multi-jointed, and therefore discrete, fish, we need a way to approximate the continuous posture function that describes an ideal swimming gait.
How it works
- Each joint has a start point, a cross point where it intersects the posture function, and an end point. The Liu and Hu algorithm does not require the end point to be on the function. The first joint's start point is always at (0, 0), while the rest of the joints are oriented in the +x horizontal direction. The end point of a joint is the start point of the next joint.
- The goal of the algorithm is to produce the optimal orientation of the joints to mimic the smooth posture function. Optimal is defined as minimizing the mean error between the joints and the posture function.
- Repeat for every joint:
- 1
- 1
How to run it
Hinge Movement Pattern
To implement the approximated motion of the joints on the fish we are using an Arduino to control the hinges. The motion that each hinge performs over time is a sinusoid phase shifted from the other hinges' sinusoids. To simplify the code needed on the Arduino, get_deflection_pattern determines when to move each joint to reproduce the sinusoids.
How it works
How to run it
-
Track the movement of the hinge: run get_all_deflection_angles with the output from the discretization algorithm (joint_points).
-
Get the wave characteristics of sinusoidal approximation of hinge movement: pattern run generate_deflection_sequence with the joint lengths and the posture function that you want them to approximate. A graph is also generated showing the original and approximated trajectories of all joints.
-
Get the timing between the joints you can directly plug into the Arduino: run get_deflection_pattern with the joint lengths and the posture function. A sample output could be below:
>> get_deflection_pattern([24.55, 26.1, 25, 25], @get_posture_short_fish)
ans = 3.0000 0.0726 29.6189 1.0000 0.0247 16.1928 2.0000 0.0695 29.4735
- The sample output is interpretted as so:
- The order of the joints is 3, 1, 2, 3, 1, 2...
- Joint 3 reaches its peak amplitude 72.6ms after joint 2. Joint 1 reaches its peak 24.7ms after joint 3. Joint 2 reaches its peak 69.5ms after joint 1.
- The peak amplitudes of each joint are in the 3rd column.
To use this information on the Arduino: + Indexing begins at 0 instead of 1. Therefore the order of joints from the sample output is 2, 0, 1, 2, 0, 1... + If controlling the small fish (Clink), update the variable time_since_prev_joint to the timing in ms from the first to last joint in order: [24.7, 69.5, 72.6]. + Use the graph of all trajectories from generate_deflection_sequence to determine whether the joints reach a peak or a trough after each other. For example:
- After the 3rd (red) joint reaches a peak, the next critical point is blue trough, and then the magenta peak. Therefore, the pattern is 3, 1, 2, 3, 1, 2: peak, trough, peak, trough, peak, trough, peak trough... Intuitively, the order of the joints is 1, 2, 3..., or trough, peak, trough..., so the first and third joint move in the same direction while the second one moves opposite. Set joint_directions to reflect this: 010 means left, right, left, while 000 means all left.
MATLAB was initially used to implement the joint approximation algorithm described in Liu and Hu's paper
- Dimensions of joints
- Correct posture function that joints can fit
- Get joint_points for each posture over time
- Run get_pattern...
- Translating to Arduino: 1 = 0, other stuff.