#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# Make a longer arm

edited May 11

So i'm working on something like this example:

https://processing.org/examples/arm.html

I was wondering how one could program a longer arm. As in more arm parts. I'm pretty okay with programming but this is still a bit above what i'm capable of...

This is what i'm trying to do:

http://i.imgur.com/6pJJxhu.png

• In the example, the angles the arms bend depend on the position of the mouse.

This works well because the mouse has an X and a Y component, each of which controls the angle for one of the arms.

If you are going to have an arm with more segments, you will need to determine how the angle those segments make is determined. Then you just need to do more arm segments!

Here's an example of me extending the example so that it starts with a segment who's angle depends on how much time has passed:

``````float x, y;
float angle0 = 0.0;
float angle1 = 0.0;
float angle2 = 0.0;
float segLength = 100;

void setup() {
size(640, 360);
strokeWeight(30);
stroke(255, 160);

x = width * 0.3;
y = height * 0.5;
}

void draw() {
background(0);

angle0 = map(abs(-5000+millis()%10000),0,5000,-HALF_PI,HALF_PI);
angle1 = (mouseX/float(width) - 0.5) * -PI;
angle2 = (mouseY/float(height) - 0.5) * PI;

pushMatrix();

segment(x, y, angle0);
segment(segLength, 0, angle1);
segment(segLength, 0, angle2);
popMatrix();
}

void segment(float x, float y, float a) {
translate(x, y);
rotate(a);
line(0, 0, segLength, 0);
}
``````
• edited May 19

If you want your robot arm to have multiple segments connected by joints -- eg like a chain -- consider using the Box2D Library For Processing

https://github.com/shiffman/Box2D-for-Processing

See this discussion answer for a general idea of using Box2D to model a multi-segment jointed object:

https://gamedev.stackexchange.com/a/50324

• edited May 19

Yeah, well, unless you want to do all the math, stick to Box2D or one of the other libraries to do realistic simulations (unless you're really gonna stick to some simple, boring idea).

• @Rutger1

One needs to defined how the different parts of your arm interact with each other. You will need to work with the concept of forces and in this case, you need to work with the concept of torques. Imaging your 5-piece arm all coiled up, or the tip of the arm driven to the beginning of the arm, toward the main pivot point. How will the other parts behave? When doing this type of programming, you will need to design your program to manage all the interactions of your robotic arm. This is why it is suggested to look at box2D library as it does all the work for you. If you want to stick to processing code and do all the calculations yourself, then you should stick to TfGuy44 example and master his code and then take it from there.

For box2D check: http://natureofcode.com/book/chapter-5-physics-libraries/ and go to section 5.11 and 5.18 just to have a glimpse...

Interesting enough, your multiple arm idea is a simple approach or how a cord (a string line) will behave if there was not gravity. Here on Earth, you will need to include the downward pulling force so you system will be acting under some constrains. In other words, you will need to put extra code to make it work on Earth ;;)

Kf

• Hello,

an arm with segments can be done easily using a Logo turtle approach.

see

https://en.wikipedia.org/wiki/Logo_(programming_language)#Turtle_and_graphics

The hard part is to make it follow the mouse, I haven't done this yet.

you could direct each angle with keyboard keys though.

here is an example with random movements using Logo turtle approach (forward, left). Press any key.

Best, Chrisir ;-)

``````/**
* this is for a robot arm:
* https://forum.processing.org/two/discussion/22518/make-a-longer-arm#latest
* using Logo Turtle approach :
* Turtle3D RectBox
* 2017-02-07 by Jeremy Douglass - Processing 3.2.3
* https:// forum.processing.org/two/discussion/20706/how-3d-turtle-like-in-logo-but-3d-math-problem
*/

color RED = color(255, 2, 2);
color GREEN = color(0, 255, 2);
color BLUE = color(2, 2, 255);

color GRAY = color(127);
color DARKGRAY = color(90);
color LIGHTGRAY = color(167);

color WHITE = color(255);
color BLACK = color(0);

// when I grow up I'll become a class
int max=6;
float[] angles= new float [max];
float[] movement= new float [max];
PVector[] position = new PVector[max];
// must have max or more colors:
RED, GREEN, BLUE, WHITE,
LIGHTGRAY, DARKGRAY, GRAY, RED,
GREEN, BLUE, WHITE, LIGHTGRAY,
DARKGRAY, GRAY,
RED, GREEN, BLUE, WHITE};

boolean movementAllowed = false;
int timeStart;

// ---------------------------------------------------------

void setup() {
size(1300, 800);
strokeWeight(5);
init();
}

void draw() {
background(192);

fill(0);
text("press any key", width/2, 330);

if (millis()-timeStart>1000) {
movementAllowed=true;
}

pushMatrix();
translate(width/2, height-10) ;
left(90);
robotArm();
popMatrix();

for (int i=0; i<angles.length-1; i++) {
noStroke();
fill(LIGHTGRAY);
ellipse(position[i].x, position[i].y, 11, 11);
fill(BLACK);
ellipse(position[i].x, position[i].y, 3, 3);
}
}

// ------------------------------------------------------

void robotArm() {

int lengthSegment = 90;

fill(0);
noStroke();
// x,y are swapped here
rect(-10, -30, 10, 60);

pushMatrix();

// display
for (int i=0; i<angles.length; i++) {
position[i]=new PVector( screenX(0, 0), screenY(0, 0) );
}

// move the arm
if (movementAllowed) {
for (int i=0; i<angles.length; i++) {
// move the arm
angles[i]+=movement[i];
// boundaries
if (angles[i]>70)
movement[i]=-abs(movement[i]);
if (angles[i]<-70)
movement[i]=abs(movement[i]);
}
}
popMatrix();

//
}

void segment( float angle, int lengthSegment, color col ) {
// one segment of the arm
stroke(col);

right(angle);
forward(lengthSegment);
}

// -----------------------------------------------------

void keyPressed() {
movementAllowed=false;
timeStart=millis();
init();
}

// -----------------------------------------------------

void init() {
for (int i=0; i<angles.length; i++) {
angles[i]=random(-75, 75);
movement[i]=random(-1.3, 1.3);
}
}

// -----------------------------------------------------
// turtle functions

void forward(int x) {
line(0, 0, x, 0);
translate(x, 0);
}

void forwardJump(int x) {
translate(x, 0);
}

void left(float amount) {
// expects degree
}

void right(float amount) {
// expects degree
}
//
``````
• edited May 21

@kfrajer Yes, but for more intuitive movement of a string, you need to have finite elasticity = more work :D

• Did you try mine?

What do you mean by finite elasticity?

• I just realized that the initial example also works with a kind of Logo turtle in that the coordinates do add up

• and mouse support using none mouse button, left mouse button and right mouse button

``````/**
* this is for a robot arm:
*
* https://forum.processing.org/two/discussion/22518/make-a-longer-arm#latest
* using :
* Turtle3D RectBox
* 2017-02-07 Jeremy Douglass - Processing 3.2.3
* https:// forum.processing.org/two/discussion/20706/how-3d-turtle-like-in-logo-but-3d-math-problem
*/

// constants
color RED = color(255, 2, 2);
color GREEN = color(0, 255, 2);
color BLUE = color(2, 2, 255);

color GRAY = color(127);
color DARKGRAY = color(90);
color LIGHTGRAY = color(167);

color WHITE = color(255);
color BLACK = color(0);

// when I grow up I'll become a class
// data on the segments
int max=6;
float[] angles= new float [max];  // all in degree
float[] movement= new float [max];
PVector[] position = new PVector[max];
// must have "max" or more colors:
RED, GREEN, BLUE, WHITE,
LIGHTGRAY, DARKGRAY, GRAY, RED,
GREEN, BLUE, WHITE, LIGHTGRAY,
DARKGRAY, GRAY,
RED, GREEN, BLUE, WHITE};

boolean movementAllowed = false;
int timeStart;
int timeDuration=990;
boolean autoReset = false;

// ---------------------------------------------------------

void setup() {
size(1300, 800);
strokeWeight(5);
init();
}

void draw() {
background(192);

mousePressedCall();

fill(0);
textAlign(CENTER);
text("press any key for a random form\n\n"
+"move mouse x,y for segments 0&1\n"
+"click left mouse button and move mouse x,y for segments 2&3\n"
+"click right mouse button and move mouse x,y for segments 4&5\n",
width/2, 130);
textAlign(LEFT);

if (millis()-timeStart>timeDuration) {
// movementAllowed=true;
}

if (autoReset) {
if (random(100)>97)
init();
}

pushMatrix();
translate(width/2, height-10) ;
left(90);
robotArm();
popMatrix();

// show the joints extra
for (int i=0; i<angles.length-1; i++) {
noStroke();
fill(LIGHTGRAY);
ellipse(position[i].x, position[i].y, 11, 11);
fill(BLACK);
ellipse(position[i].x, position[i].y, 3, 3);
}

for (int i=1; i<angles.length; i++) {
// too far down?
if (position[i].y>height-30) {

// too far down on right side?
if (position[i].x>width/2+10) {
// right side
// make the joint before go left
int i3=i-1;
movement[i3]=-abs(movement[i3]);
// Or make all the joint before it go left
for (int i2=i-1; i2>0; i2--) {
// movement[i2]=-abs(movement[i2]);
}
} else {
// left side
// make the joint before go right
int i3=i-1;
movement[i3]=abs(movement[i3]);
// Or make all the joint before it go left
for (int i2=i-1; i2>0; i2--) {
// movement[i2]=abs(movement[i2]);
}
}
}
}//for
//
}

// ------------------------------------------------------

void robotArm() {

int lengthSegment = 90;

// the box the arm is standing on
fill(0);
noStroke();
// x,y are swapped here
rect(-10, -30, 10, 60);

pushMatrix();

// display
for (int i=0; i<angles.length; i++) {
position[i]=new PVector( screenX(0, 0), screenY(0, 0) );
}

// move the arm
if (movementAllowed) {
for (int i=0; i<angles.length; i++) {
// move the arm
angles[i]+=movement[i];
// boundaries
if (angles[i]>70)
movement[i]=-abs(movement[i]);
if (angles[i]<-70)
movement[i]=abs(movement[i]);
}
}
popMatrix();
//
}

void segment( float angle, int lengthSegment, color col ) {

// one segment of the arm

stroke(col);

right(angle);
forward(lengthSegment);
}

// -----------------------------------------------------

void keyPressed() {
movementAllowed=false;
timeStart=millis();
init();
}

void mousePressedCall() {

int index0=0;
int index1=1;
if (mouseButton==LEFT) {
index0=2;
index1=3;
} else if (mouseButton==RIGHT) {
index0=4;
index1=5;
}

// formula for degree
float calcAnglesIndex0  = (mouseX/float(width) - 0.5) * (2*70); // those 2 do the same thing
float calcAnglesIndex1  = map ( mouseY, 0, height, -70, 70);

//
angles[index0] += calcAnglesIndex0-angles[index0] ;
angles[index1] += calcAnglesIndex1-angles[index1] ;
}

void mousePressedCall_Old_Version() {

int index0=0;
int index1=1;
if (mouseButton==LEFT) {
index0=2;
index1=3;
} else if (mouseButton==RIGHT) {
index0=4;
index1=5;
}

// formula for degree
angles[index0] = (mouseX/float(width) - 0.5) * (2*70);
angles[index1] = map ( mouseY, 0, height, -70, 70);
}

// -----------------------------------------------------

void init() {
for (int i=0; i<angles.length; i++) {

angles[i]   = random(-75, 75);

movement[i] = random(0.3, 1.0);
if (random(100)>50)
movement[i]*=1;
}//for
}//func

// -----------------------------------------------------
// turtle functions

void forward(int x) {
// turtle goes x steps forward drawing a line
line(0, 0, x, 0);
translate(x, 0);
}

void forwardJump(int x) {
// turtle jumps x steps forward without drawing a line
translate(x, 0);
}

void right(float amount) {
// turtle rotates right on the spot without drawing
// expects degree
}

void left(float amount) {
// turtle rotates left on the spot without drawing
// expects degree