small fish control - ksoltan/RoboFish GitHub Wiki

small-fish-control.ino

Controls a 3 jointed fish, tested on Clinky. Uses the output of get_deflection_pattern in MATLAB with the specific lengths of joints and the function that should describe its motion.

Variables:

  • NUM_JOINTS: number of joints in the system

  • joint_order: order of movement of joints. Usually 0, 1, 2, 0, 1, 2,... 0 represents the head joint, NUM_JOINTS - 1 represents the last joint.

  • joint_idx: index of current joint in joint_order.

  • joint_to_move: joint_order[joint_idx] in case the joint order do not line up with joint indeces (joint_order[0] != 0).

  • joint_directions: each bit of the integer represents a different joint. A 0 means it is currently moved LEFT, and 1 means it is currently in the RIGHT position.

  • time_since_prev_joint: number of ms between the peaks of consecutive joints. These numbers come from the MATLAB approximation. Make sure that the numbers are in ms and that they correspond to the correct joint. The ith value is the amount of time that must pass after the i-1th joint before the ith joint peaks.

  • joint_duty: duty cycle at which to run each joint to naively control its amplitude. Values are based on the output of the MATLAB approximation. If the amplitudes of joints 0, 1, 2 are 10, 22, 25, then the duty cycles would represent the relative amplitudes: 50, 100, 100, as the 0th joint is half of the amplitude of the other two. This is a very naive way and not extensively tested.

  • joint_pins: array of pairs of (left_pin, right_pin) for each joint, in the order of 0, 1, 2 joints, no matter if joint_order is not the consecutive joints.

Functions:

  • loop(): void

    Main function. If the time since the last joint was moved is less than the time between the next joint's peak, do nothing. If the time is greater:

    • move the next joint (to it's peak position)
    • update the last time a joint was moved
    • update the next joint idx and joint to move
  • flap(int dir, int duty): void

    Moves the joint_to_move to the specified direction with the specified duty cycle which naively represents the amplitude to which to move the joint.

  • moveNextJoint(): void

    • Determines the position in which the joint_to_move is (left or right)
    • Calls the flap function with the opposite direction
    • Updates the correct bit in joint_directions to represent the direction to which joint_to_move has been moved.

Notes

This sketch has yet to produce a convincing fish motion on Clinky. This is due to two things:

  1. The time_since_prev_joint represents the time between peaks, and therefore the joints should be moving in their respective directions the entire time. Currently, this is simple bang-bang control, so the joint switches direction almost instantaneously at the moment it should just be peaking, coming to a stop, and reversing direction.

  2. The duty cycle does not convincingly vary the amplitude of the joint. More testing needs to be done to determine how to actually control the position of the joint.