fn do_instruction(&mut self, motion: &mut WorldStepInfo, arm_id: usize, timestep: u64) -> SimResult<()>{
        assert_eq!(motion.arms.len(), arm_id, "Arm motion array not same as arm ID");
        let arm = &mut self.arms[arm_id];
        use ArmType::*;
        use Instr::*;
        use Movement::*;
        use ArmMovement::*;
        let arm_type = arm.arm_type;
        let tape = &arm.instruction_tape;
        let timestep = timestep as usize;
        let instruction = tape.get(timestep, self.repeat_length);
        const STILL: ArmMovement = Move(HeldStill);
        let action = match instruction {
            Extend => {
                if arm_type == Piston && arm.len < 3 {
                    LengthAdjust(1)
                } else { STILL }
            }
            Retract => {
                if arm_type == Piston && arm.len > 1 {
                    LengthAdjust(-1)
                } else { STILL }
            }
            RotateCounterClockwise => {
                Move(Rotation(1, arm.pos))
            }
            RotateClockwise => {
                Move(Rotation(-1, arm.pos))
            }
            PivotCounterClockwise => Pivot(1),
            PivotClockwise => Pivot(-1),
            Drop => {
                if arm_type != VanBerlo {
                    arm.atoms_grabbed = [AtomKey::null(); 6];
                    arm.grabbing = false;
                }
                STILL
            }
            Grab => {
                if !arm.grabbing && arm_type != VanBerlo {
                    arm.grabbing = true;
                    for r in (0..6).step_by(Arm::angles_between_arm(arm.arm_type) as usize) {
                        let grab_pos = arm.pos + (rot_to_pos(arm.rot + r) * arm.len);
                        let null_key = AtomKey::null();
                        let mut current = self.atoms.locs.get(&grab_pos).unwrap_or(&null_key);
                        if current != &null_key{
                            if self.atoms.atom_map[*current].is_berlo{
                                current = &null_key;
                            }
                        }
                        arm.atoms_grabbed[r as usize] = *current;
                    }
                }
                STILL
            }
            Forward => {
                let track_data = self.track_map.get(&arm.pos)
                    .ok_or(sim_error_pos("Forward movement not on track", arm.pos))?;
                track_data.plus.map_or(STILL, |x| {
                    Move(Linear(x))
                })
            }
            Back => {
                let track_data = self.track_map.get(&arm.pos)
                    .ok_or(sim_error_pos("Backward movement not on track", arm.pos))?;
                track_data.minus.map_or(STILL, |x| {
                    Move(Linear(x))
                })
            }
            Repeat | Reset | Noop => {
                panic!("Unprocessed instruction!");
            }
            Empty => (STILL),
        };
        let rotation_store = arm.rot;
        for atom in arm.atoms_grabbed {
            if !atom.is_null() {
                let atom_movement = match action{
                    ArmMovement::Pivot(r) => Movement::Rotation(r, self.atoms.atom_map[atom].pos),
                    ArmMovement::Move(m) => m,
                    ArmMovement::LengthAdjust(a) => Linear(rot_to_pos(rotation_store)*a)
                };
                self.premove_atoms(motion, atom, atom_movement)?;
            }
        }
        motion.arms.push(action);
        Ok(())
    }
//Returns the movement the arm is going to do. Returns size of the largest molecule rotated
Returns the movement the arm is going to do. Returns size of the largest molecule rotated
Returns the movement the arm is going to do . Returns size of the largest molecule rotated
fn do_instruction(&mut self, motion: &mut WorldStepInfo, arm_id: usize, timestep: u64) -> SimResult<()>{
        assert_eq!(motion.arms.len(), arm_id, "Arm motion array not same as arm ID");
        let arm = &mut self.arms[arm_id];
        use ArmType::*;
        use Instr::*;
        use Movement::*;
        use ArmMovement::*;
        let arm_type = arm.arm_type;
        let tape = &arm.instruction_tape;
        let timestep = timestep as usize;
        let instruction = tape.get(timestep, self.repeat_length);
        const STILL: ArmMovement = Move(HeldStill);
        let action = match instruction {
            Extend => {
                if arm_type == Piston && arm.len < 3 {
                    LengthAdjust(1)
                } else { STILL }
            }
            Retract => {
                if arm_type == Piston && arm.len > 1 {
                    LengthAdjust(-1)
                } else { STILL }
            }
            RotateCounterClockwise => {
                Move(Rotation(1, arm.pos))
            }
            RotateClockwise => {
                Move(Rotation(-1, arm.pos))
            }
            PivotCounterClockwise => Pivot(1),
            PivotClockwise => Pivot(-1),
            Drop => {
                if arm_type != VanBerlo {
                    arm.atoms_grabbed = [AtomKey::null(); 6];
                    arm.grabbing = false;
                }
                STILL
            }
            Grab => {
                if !arm.grabbing && arm_type != VanBerlo {
                    arm.grabbing = true;
                    for r in (0..6).step_by(Arm::angles_between_arm(arm.arm_type) as usize) {
                        let grab_pos = arm.pos + (rot_to_pos(arm.rot + r) * arm.len);
                        let null_key = AtomKey::null();
                        let mut current = self.atoms.locs.get(&grab_pos).unwrap_or(&null_key);
                        if current != &null_key{
                            if self.atoms.atom_map[*current].is_berlo{
                                current = &null_key;
                            }
                        }
                        arm.atoms_grabbed[r as usize] = *current;
                    }
                }
                STILL
            }
            Forward => {
                let track_data = self.track_map.get(&arm.pos)
                    .ok_or(sim_error_pos("Forward movement not on track", arm.pos))?;
                track_data.plus.map_or(STILL, |x| {
                    Move(Linear(x))
                })
            }
            Back => {
                let track_data = self.track_map.get(&arm.pos)
                    .ok_or(sim_error_pos("Backward movement not on track", arm.pos))?;
                track_data.minus.map_or(STILL, |x| {
                    Move(Linear(x))
                })
            }
            Repeat | Reset | Noop => {
                panic!("Unprocessed instruction!");
            }
            Empty => (STILL),
        };
        let rotation_store = arm.rot;
        for atom in arm.atoms_grabbed {
            if !atom.is_null() {
                let atom_movement = match action{
                    ArmMovement::Pivot(r) => Movement::Rotation(r, self.atoms.atom_map[atom].pos),
                    ArmMovement::Move(m) => m,
                    ArmMovement::LengthAdjust(a) => Linear(rot_to_pos(rotation_store)*a)
                };
                self.premove_atoms(motion, atom, atom_movement)?;
            }
        }
        motion.arms.push(action);
        Ok(())
    }
fn do_instruction ( & mut self , motion : & mut WorldStepInfo , arm_id : usize , timestep : u64 ) -> SimResult < ( ) > { assert_eq ! ( motion arms len ( ) arm_id " " ) ; let arm = & mut self . arms [ arm_id ] ; use ArmType :: * ; use Instr :: * ; use Movement :: * ; use ArmMovement :: * ; let arm_type = arm . arm_type ; let tape = & arm . instruction_tape ; let timestep = timestep as usize ; let instruction = tape . get ( timestep , self . repeat_length ) ; const STILL : ArmMovement = Move ( HeldStill ) ; let action = match instruction { Extend => { if arm_type == Piston && arm . len < 3 { LengthAdjust ( 1 ) } else { STILL } } Retract => { if arm_type == Piston && arm . len > 1 { LengthAdjust ( - 1 ) } else { STILL } } RotateCounterClockwise => { Move ( Rotation ( 1 , arm . pos ) ) } RotateClockwise => { Move ( Rotation ( - 1 , arm . pos ) ) } PivotCounterClockwise => Pivot ( 1 ) , PivotClockwise => Pivot ( - 1 ) , Drop => { if arm_type != VanBerlo { arm . atoms_grabbed = [ AtomKey :: null ( ) ; 6 ] ; arm . grabbing = false ; } STILL } Grab => { if ! arm . grabbing && arm_type != VanBerlo { arm . grabbing = true ; for r in ( 0 .. 6 ) . step_by ( Arm :: angles_between_arm ( arm . arm_type ) as usize ) { let grab_pos = arm . pos + ( rot_to_pos ( arm . rot + r ) * arm . len ) ; let null_key = AtomKey :: null ( ) ; let mut current = self . atoms . locs . get ( & grab_pos ) . unwrap_or ( & null_key ) ; if current != & null_key { if self . atoms . atom_map [ * current ] . is_berlo { current = & null_key ; } } arm . atoms_grabbed [ r as usize ] = * current ; } } STILL } Forward => { let track_data = self . track_map . get ( & arm . pos ) . ok_or ( sim_error_pos ( " " , arm . pos ) ) ? ; track_data . plus . map_or ( STILL , | x | { Move ( Linear ( x ) ) } ) } Back => { let track_data = self . track_map . get ( & arm . pos ) . ok_or ( sim_error_pos ( " " , arm . pos ) ) ? ; track_data . minus . map_or ( STILL , | x | { Move ( Linear ( x ) ) } ) } Repeat | Reset | Noop => { panic ! ( " " ) ; } Empty => ( STILL ) , } ; let rotation_store = arm . rot ; for atom in arm . atoms_grabbed { if ! atom . is_null ( ) { let atom_movement = match action { ArmMovement :: Pivot ( r ) => Movement :: Rotation ( r , self . atoms . atom_map [ atom ] . pos ) , ArmMovement :: Move ( m ) => m , ArmMovement :: LengthAdjust ( a ) => Linear ( rot_to_pos ( rotation_store ) * a ) } ; self . premove_atoms ( motion , atom , atom_movement ) ? ; } } motion . arms . push ( action ) ; Ok ( ( ) ) }
Returns the movement the arm is going to do.
Returns the movement the arm is going to do .
&mut self
motion
&mut WorldStepInfo
arm_id
usize
timestep
u64
&mut self
motion
&mut WorldStepInfo
arm_id
usize
timestep
u64