LegoMindstormsRobots.com

Shape-Changing Rotacaster Flexi-Bot

GD Star Rating
loading...

The Shape-Changing Rotacaster Flexi-Bot acts like a Chameleon, but instead of changing colour, it can morphs into a variety of different  leg configurations. The front and rear pairs of arms are controlled as a pairs change the configuration of the Rotacaster Omni-wheels relative to the Robots body. Each Rotacaster Omni-wheel is driven individually via a Small Lego Power Functions Motor. The Arm pairs are driven individually by a pair of Lego Mindstorms NXT Servo Motors.

Rotacaster Flex-Bot

The home position for the arms is controlled via a set of 4x Lego Mindstorms RCX type Touch Sensors before the position of the NXT Servo Motors is set. The Power Function Motors are controlled via a Hitechnic Infra-red Link Sensor and 2x Lego Power Function Infra-red receivers. The Robot is controlled via a Sony PlayStation2 Controller interfaced to a Mindsensor PSP-Nx-v3: Sony PlayStation2 Controller interface for the NXT.

Rotacaster Flex-Bot


Lego Mindstorms NXT Rotacaster Flexi-Bot in Action!

I was forced to make a few minor changes between the Robot in the Video and the Photographs to accommodate the size of the stage. I was forced to change the gear ratio by a factor of  1:3 for the drive to the Rotacasters instead of the pictured direct-drive. This was primarily to slow it down so I was able to keep it on the mat.

The other change was to move the Battery Box for the PowerFunction Motors, from under the NXT to beside it, to aid in ease of battery changing.

Rotacaster Flex-Bot

The Flexi-Bot does work on carpet, but due to the weight of the Robot it bogs down somewhat. Also the Rotacasters don't have the surface area to ensure good tracking with the wheels off-set from each other. Larger Rotacasters would solve this issue I feel. But, most Robot designs tend to be somewhat lighter than this example. My post: Rotacaster Omni-wheels in Action! preforms very well on my 100% wool carpet.

Rotacaster Flex-Bot

All-in-all, I'm very happy with the Flexi-Bot results. For it to preform at it's best it needs a large floor space of at least 5m X 5m. The Rotacasters are at their best on polished wooden or Vinyl floor coverings, which I lack in a large enough scale to allow me too enjoy all the fun the Robot offers.

Rotacaster Flex-Bot




Buy Rotacaster Omni-wheels




Rotacaster Flex-Bot

Rotacaster Flex-Bot

Rotacaster Flex-Bot

NXC Source Code:

/* ===================================================

           ***********************************
           ****** Rotacaster Flexi Bot  ******
           ***********************************
           
   =================================================== */

#define PS2           S1     // Port Number
#define F_Touch       S2     // Port Number
#define R_Touch       S3     // Port Number
#define PF_CTL        S4     // Port Number
#define ADDR          0x02
#define Deg2Rot       360
#define FrontSW       SENSOR_2
#define RearSW        SENSOR_3
#include "PSP-Nx-lib.nxc"

const byte PlayStation  =  PS2;
const int Degrees = (Deg2Rot * 1);

int Position, MovePosition, PositionFront, PositionRear, Direction;

/* ===================================================
             Check & Display Sensors State
   =================================================== */

task DisplayData()
{
  ClearScreen();
  while (true)
  {
    TextOut(0,  LCD_LINE1, "Front Sw =       ");
    NumOut(80, LCD_LINE1, FrontSW);
    TextOut(0,  LCD_LINE2, "Rear Sw  =       ");
    NumOut(80, LCD_LINE2, RearSW);
    TextOut(0,  LCD_LINE3, "Position =       ");
    NumOut(75, LCD_LINE3, Position);
    TextOut(0,  LCD_LINE4, "Direction =      ");
    NumOut(75, LCD_LINE4, Direction); 
    TextOut(0,  LCD_LINE7, "PosF       ");
    NumOut(30, LCD_LINE7, PositionFront);
    TextOut(50,  LCD_LINE7, "PosR       ");
    NumOut(80, LCD_LINE7, PositionRear);
    Wait (50);
  }
}


/* ===================================================
                    Initilize the Robot
   =================================================== */

void Initilize()
{
  OnFwd(OUT_AB, 75);
  Wait(750);
  Off(OUT_AB);

  do
  {
    OnRev(OUT_A, 100);
    Wait (50);
  }
  while (RearSW != true)

  Off(OUT_A);
  Wait(100);
  ResetTachoCount(OUT_A);


  do
  {
    OnRev(OUT_B, 100);
    Wait (50);
  }
  while (FrontSW != true)

 Off(OUT_AB);
  Wait(100);

  PlayTone(1400, 100);

  PositionFront = 0; PositionRear = 0;
}




/* ===================================================
                    Move All Robot Legs
   =================================================== */

void Legs(float Angle)
{
  if (PositionFront == PositionRear)
  {
      MovePosition = 0 - PositionRear + Angle;
      if (MovePosition == 0 ) { return; }
      if ( sign (MovePosition) == -1) { Direction = -100; } else Direction = 100;
      Position = abs(MovePosition *100);
      OnFwd(OUT_AB, Direction);
      RotateMotor(OUT_AB, Direction, Position);
      Off(OUT_AB);
      PositionRear = Angle;
      PositionFront = Angle;
      PlayTone(500, 100);
      return;
  }


  PlayTone(750, 100);
  TextOut(0,  LCD_LINE1, "Angel=                       ");
  NumOut(50, LCD_LINE1, Angle);
  MovePosition = 0 - PositionRear + Angle;
  if (MovePosition == 0 ) { return; }
  if ( sign (MovePosition) == -1) { Direction = -100; } else Direction = 100;
  Position = abs(MovePosition *100);
  OnFwd(OUT_A, Direction);
  RotateMotor(OUT_A, Direction, Position);
  Off(OUT_A);
  PositionRear = Angle;
  PlayTone(500, 100);

  MovePosition = 0 - PositionFront + Angle;
  if (MovePosition == 0 ) { return; }
  if ( sign (MovePosition) == -1) { Direction = -100; } else Direction = 100;
  Position = abs(MovePosition *100);
  OnFwd(OUT_B, Direction);
  RotateMotor(OUT_B, Direction, Position);
  Off(OUT_B);
  PositionFront = Angle;
  PlayTone(500, 200);
}


/* ===================================================
                    Move Robot Front Legs 'F'
   =================================================== */

void LegsF(float Angle)
{
  PlayTone(750, 100);
  MovePosition = 0 - PositionFront + Angle;
  if (MovePosition == 0 ) { return; }
  if ( sign (MovePosition) == -1) { Direction = -100; } else Direction = 100;
  Position = abs(MovePosition *100);
  OnFwd(OUT_B, Direction);
  RotateMotor(OUT_B, Direction, Position);
  Off(OUT_B);
  PositionFront = Angle;
  PlayTone(500, 100);
}


/* ===================================================
                    Move Robot Rear Legs'R'
   =================================================== */

void LegsR(float Angle)
{
  PlayTone(750, 100);
  MovePosition = 0 - PositionRear + Angle;
  if (MovePosition == 0 ) { return; }
  if ( sign (MovePosition) == -1) { Direction = -100; } else Direction = 100;
  Position = abs(MovePosition *100);
  OnFwd(OUT_A, Direction);
  RotateMotor(OUT_A, Direction, Position);
  Off(OUT_A);
  PositionRear = Angle;
  PlayTone(500, 100);
}


/* ===================================================
                        Main Tasks
   =================================================== */

task main()
{
  ResetSensor(F_Touch);
  ResetSensor(R_Touch);

  SetSensorLowspeed(PS2);
  SetSensor(F_Touch, SENSOR_TOUCH);
  SetSensor(R_Touch, SENSOR_TOUCH);
  SetSensorMode(F_Touch, IN_MODE_BOOLEAN);
  SetSensorMode(R_Touch, IN_MODE_BOOLEAN);
  ClearSensor(R_Touch);
  ClearSensor(F_Touch);

  SetSensorLowspeed(PF_CTL);
	Wait (10);
	
  psp currState;
  start DisplayData;

  RotateMotor(OUT_AB, 100, 360);
  Off(OUT_AB);

  Initilize();

/*--------------------------------------
  PS2 Controller button layout:
----------------------------------------

      L1                R1
      L2                R2

      d                 triang
   a     c         square     circle
      b                  cross

     l_j_b              r_j_b
     l_j_x              r_j_x
     l_j_y              r_j_y

-------------------------------------- */
/*
  bits as follows:
   b1:   a b c d x r_j_b l_j_b x
   b2:   square cross circle triang R1 L1 R2 L2
*/

  while (true)
  {
        Off(OUT_AB);

        PSP_ReadButtonState(PlayStation, ADDR, currState);

        if (currState.square != true) { Legs(90); }

        if (currState.cross != true) { Legs(45); }
        
        if (currState.triang != true) { Legs(135); }

        if (currState.circle != true) { Legs(0); }

        if (currState.l1 != true) { LegsF(45); }
        
        if (currState.r1 != true) { LegsR(45); }

        if (currState.l2 != true) { LegsF(135); }

        if (currState.r2 != true) { LegsR(135); }

        if (currState.d != true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_REV, PF_CMD_REV); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_FWD, PF_CMD_FWD);
        if (currState.d == true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_STOP, PF_CMD_STOP); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_STOP, PF_CMD_STOP); }}

        if (currState.b != true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_FWD, PF_CMD_FWD); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_REV, PF_CMD_REV);
        if (currState.b == true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_STOP, PF_CMD_STOP); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_STOP, PF_CMD_STOP); } }

        if (currState.a != true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_REV, PF_CMD_FWD); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_FWD, PF_CMD_REV);
        if (currState.a == true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_STOP, PF_CMD_STOP); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_STOP, PF_CMD_STOP); } }

        if (currState.c != true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_FWD, PF_CMD_REV); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_REV, PF_CMD_FWD);
        if (currState.c == true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_STOP, PF_CMD_STOP); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_STOP, PF_CMD_STOP); } }

        if (currState.l_j_b != true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_REV, PF_CMD_REV); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_REV, PF_CMD_REV);
        if (currState.l_j_b == true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_STOP, PF_CMD_STOP); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_STOP, PF_CMD_STOP); } }

        if (currState.r_j_b != true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_FWD, PF_CMD_FWD); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_FWD, PF_CMD_FWD);
        if (currState.r_j_b == true) { HTPFComboDirect(PF_CTL, PF_CHANNEL_1, PF_CMD_STOP, PF_CMD_STOP); HTPFComboDirect(PF_CTL, PF_CHANNEL_2, PF_CMD_STOP, PF_CMD_STOP); } }

        Wait (50);
  }

}



 

Rotacaster Flex-Bot




Buy Rotacaster Omni-wheels




GD Star Rating
loading...
GD Star Rating
loading...
Shape-Changing Rotacaster Flexi-Bot, 6.0 out of 10 based on 1 rating

Tags: , , , , , , , , , , , , , , , , , , , , , , ,

1

“… you just can't differentiate between a robot and the very best of humans.” ― Isaac Asimov, I, Robot