Braccio Tinkerkit Robot Startup Position

I just recently purchased the Braccio tinkerkit robot and got the Sponge example working great, however, I am confused how this is working.

As I understand controlling a servo motor, the arduino assumes a "home" starting position upon bootup, and everything goes from there. What I am seeing with my Braccio is that no matter what position I align all the servos when it is powered off, after powering up, it always returns to the same position. How is this possible without sensor kit to determine location of each servo?

With standard hobby servos, there is no way to know what position the arm might have on startup.

You simply command the servo arm to move to a certain angle.

That is exactly what I said Inunderstand should be happening......, but not what I am seeing. No matter my position at power up, it is going back to same location.

Sorry, I don't understand what you are trying to say. Most programs initialize the servos to some arbitrary position (e.g. zero) upon startup.

Post the code, using code tags.

That's right. At the beginning of your code is the first set of servo commands that tell the arm where to go to begin. No matter how the arm is positioned when the code isn't running, once the code starts and it sends that initial set of servo commands then it will go to the commanded position.

If you want to start in a different position, then you will need to change the positions in that initial set of servo commands which are somewhere in the code that you didn't post.

If you want the arm to start in whatever position it was in when it was turned on, then the controller will need some way to determine that position. That required expensive servos that can read their own position.

It is pretty much the exact code from the example from braccio library called "takethesponge", but I just added a few lines to drop and pick the sponge up again. Heres what I don't understand. If I run this code, the robot turns on, goes to a starting position, and then begins looping through the code to pick up and drop the sponge. I don't understand how the arm repeats its position every time I power up regardless of the off position. I thought maybe the program took every motor past the limit in one direction, and then returned a certain amount, but that doesn't appear to be the case either. Shouldn't it essentially assume all motors are in a certain position at startup, and then everything should be relative to that?

#include <Braccio.h>
#include <Servo.h>


Servo base;
Servo shoulder;
Servo elbow;
Servo wrist_rot;
Servo wrist_ver;
Servo gripper;


void setup() {  

  Braccio.begin();
}

void loop() {

  //Starting position
                      //(step delay  M1 , M2 , M3 , M4 , M5 , M6);
  Braccio.ServoMovement(20,           0,  45, 180, 180,  90,  45);
  
  //Wait 1 second
  delay(1000);

  //The braccio moves to the sponge. Only the M2 servo will moves
  Braccio.ServoMovement(20,           0,  100, 180, 190,  90,   45);

  //Close the gripper to take the sponge. Only the M6 servo will moves
  Braccio.ServoMovement(20,           0,  100, 180, 190,  90,  73 );

  //Brings the sponge upwards.
  Braccio.ServoMovement(20,         0,   45, 180,  45,  0, 73);

  //Show the sponge. Only the M1 servo will moves
  Braccio.ServoMovement(20,         180,  45, 180,   45,   0,  73);

   Braccio.ServoMovement(20,         180,  100, 180,   45,   0,  73);

   Braccio.ServoMovement(20,         180,  100, 180,   175,   90,  73);

   Braccio.ServoMovement(20,         180,  100, 180,   175,   90,  45);

   Braccio.ServoMovement(20,         180,  0, 180,   175,   90,  45);

   Braccio.ServoMovement(20,         180,  100, 180,   175,   90,  45);

   Braccio.ServoMovement(20,         180,  100, 180,   175,   90,  73);

delay(1000);

  //Show the sponge. Only the M1 servo will moves
  Braccio.ServoMovement(20,         0,  45, 180,   45,   0,  73);

  Braccio.ServoMovement(20,           0,  45, 180, 190,  90,  73);

  //Return to the start position.
  Braccio.ServoMovement(20,         0,   100, 180,  190,  90, 73);

  //Open the gripper
  Braccio.ServoMovement(20,         0,   100, 180,  190,  90, 45 );


}

Study the code in the library function Braccio.begin().

Do you understand what this line does, at the beginning of loop()?

  //Starting position
                      //(step delay  M1 , M2 , M3 , M4 , M5 , M6);
  Braccio.ServoMovement(20,           0,  45, 180, 180,  90,  45);

that is just a movement after the .begin() function gets to the real starting position. Once in the loop, that is just a point it hits everytime in the circle of picking and dropping the sponge. Here is the code for the subfunctions. In there is the .begin() that writes all the positions to zero, so again I don't understand how it goes back to same orientation no matter what.

/*
 Braccio.cpp - board library Version 2.0
 Written by Andrea Martino and Angelo Ferrante

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "Braccio.h"

extern Servo base;
extern Servo shoulder;
extern Servo elbow;
extern Servo wrist_rot;
extern Servo wrist_ver;
extern Servo gripper;

extern int step_base = 0;
extern int step_shoulder = 45;
extern int step_elbow = 180;
extern int step_wrist_rot = 180;
extern int step_wrist_ver = 90;
extern int step_gripper = 10;
 

_Braccio Braccio;

//Initialize Braccio object
_Braccio::_Braccio() {
}

/**
 * Braccio initialization and set intial position
 * Modifing this function you can set up the initial position of all the
 * servo motors of Braccio
 * @param soft_start_level: default value is 0 (SOFT_START_DEFAULT)
 * You should set begin(SOFT_START_DISABLED) if you are using the Arm Robot shield V1.6
 * SOFT_START_DISABLED disable the Braccio movements
 */
unsigned int _Braccio::begin(int soft_start_level) {
	//Calling Braccio.begin(SOFT_START_DISABLED) the Softstart is disabled and you can use the pin 12
	if(soft_start_level!=SOFT_START_DISABLED){
		pinMode(SOFT_START_CONTROL_PIN,OUTPUT);
		digitalWrite(SOFT_START_CONTROL_PIN,LOW);
	}

	// initialization pin Servo motors
	base.attach(11);
	shoulder.attach(10);
	elbow.attach(9);
	wrist_rot.attach(6);
	wrist_ver.attach(5);
	gripper.attach(3);
        
	//For each step motor this set up the initial degree
	base.write(0);
	shoulder.write(40);
	elbow.write(180);
	wrist_ver.write(170);
	wrist_rot.write(0);
	gripper.write(73);
	//Previous step motor position
	step_base = 0;
	step_shoulder = 40;
	step_elbow = 180;
	step_wrist_ver = 170;
	step_wrist_rot = 0;
	step_gripper = 73;

	if(soft_start_level!=SOFT_START_DISABLED)
    		_softStart(soft_start_level);
	return 1;
}

/*
Software implementation of the PWM for the SOFT_START_CONTROL_PIN,HIGH
@param high_time: the time in the logic level high
@param low_time: the time in the logic level low
*/
void _Braccio::_softwarePWM(int high_time, int low_time){
	digitalWrite(SOFT_START_CONTROL_PIN,HIGH);
	delayMicroseconds(high_time);
	digitalWrite(SOFT_START_CONTROL_PIN,LOW);
	delayMicroseconds(low_time); 
}

/*
* This function, used only with the Braccio Shield V4 and greater,
* turn ON the Braccio softly and save it from brokes.
* The SOFT_START_CONTROL_PIN is used as a software PWM
* @param soft_start_level: the minimum value is -70, default value is 0 (SOFT_START_DEFAULT)
*/
void _Braccio::_softStart(int soft_start_level){      
	long int tmp=millis();
	while(millis()-tmp < LOW_LIMIT_TIMEOUT)
		_softwarePWM(80+soft_start_level, 450 - soft_start_level);   //the sum should be 530usec	

	while(millis()-tmp < HIGH_LIMIT_TIMEOUT)
		_softwarePWM(75 + soft_start_level, 430 - soft_start_level); //the sum should be 505usec

	digitalWrite(SOFT_START_CONTROL_PIN,HIGH);
}

/**
 * This functions allow you to control all the servo motors
 * 
 * @param stepDelay The delay between each servo movement
 * @param vBase next base servo motor degree
 * @param vShoulder next shoulder servo motor degree
 * @param vElbow next elbow servo motor degree
 * @param vWrist_ver next wrist rotation servo motor degree
 * @param vWrist_rot next wrist vertical servo motor degree
 * @param vgripper next gripper servo motor degree
 */
int _Braccio::ServoMovement(int stepDelay, int vBase, int vShoulder, int vElbow,int vWrist_ver, int vWrist_rot, int vgripper) {

	// Check values, to avoid dangerous positions for the Braccio
    	if (stepDelay > 30) stepDelay = 30;
	if (stepDelay < 10) stepDelay = 10;
	if (vBase < 0) vBase=0;
	if (vBase > 180) vBase=180;
	if (vShoulder < 15) vShoulder=15;
	if (vShoulder > 165) vShoulder=165;
	if (vElbow < 0) vElbow=0;
	if (vElbow > 180) vElbow=180;
	if (vWrist_ver < 0) vWrist_ver=0;
	if (vWrist_ver > 180) vWrist_ver=180;
	if (vWrist_rot > 180) vWrist_rot=180;
	if (vWrist_rot < 0) vWrist_rot=0;
    	if (vgripper < 10) vgripper = 10;
	if (vgripper >105 ) vgripper = 105;

	int exit = 1;

	//Until the all motors are in the desired position
	while (exit) 
	{			
		//For each servo motor if next degree is not the same of the previuos than do the movement		
		if (vBase != step_base) 
		{			
			base.write(step_base);
			//One step ahead
			if (vBase > step_base) {
				step_base++;
			}
			//One step beyond
			if (vBase < step_base) {
				step_base--;
			}
		}

		if (vShoulder != step_shoulder)  
		{
			shoulder.write(step_shoulder);
			//One step ahead
			if (vShoulder > step_shoulder) {
				step_shoulder++;
			}
			//One step beyond
			if (vShoulder < step_shoulder) {
				step_shoulder--;
			}

		}

		if (vElbow != step_elbow)  
		{
			elbow.write(step_elbow);
			//One step ahead
			if (vElbow > step_elbow) {
				step_elbow++;
			}
			//One step beyond
			if (vElbow < step_elbow) {
				step_elbow--;
			}

		}

		if (vWrist_ver != step_wrist_rot) 
		{
			wrist_rot.write(step_wrist_rot);
			//One step ahead
			if (vWrist_ver > step_wrist_rot) {
				step_wrist_rot++;				
			}
			//One step beyond
			if (vWrist_ver < step_wrist_rot) {
				step_wrist_rot--;
			}

		}

		if (vWrist_rot != step_wrist_ver)
		{
			wrist_ver.write(step_wrist_ver);
			//One step ahead
			if (vWrist_rot > step_wrist_ver) {
				step_wrist_ver++;
			}
			//One step beyond
			if (vWrist_rot < step_wrist_ver) {
				step_wrist_ver--;
			}
		}

		if (vgripper != step_gripper)
		{
			gripper.write(step_gripper);
			if (vgripper > step_gripper) {
				step_gripper++;
			}
			//One step beyond
			if (vgripper < step_gripper) {
				step_gripper--;
			}
		}
		
		//delay between each movement
		delay(stepDelay);
		
		//It checks if all the servo motors are in the desired position 
		if ((vBase == step_base) && (vShoulder == step_shoulder)
				&& (vElbow == step_elbow) && (vWrist_ver == step_wrist_rot)
				&& (vWrist_rot == step_wrist_ver) && (vgripper == step_gripper)) {
			step_base = vBase;
			step_shoulder = vShoulder;
			step_elbow = vElbow;
			step_wrist_rot = vWrist_ver;
			step_wrist_ver = vWrist_rot;
			step_gripper = vgripper;
			exit = 0;
		} else {
			exit = 1;
		}
	}
}

Sorry, I don't understand why you don't understand. The program ALWAYS sets the servos to the following positions upon startup. If you want something else, change the following starting positions.

	base.write(0);
	shoulder.write(40);
	elbow.write(180);
	wrist_ver.write(170);
	wrist_rot.write(0);
	gripper.write(73);

okay... it was the basics of the servo I didn't understand. I was thinking in terms of a stepper motor moving a certain number of steps from a starting position. This website helped me understand servo position is relative to constant PWM signal received.

It is all clear now..

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.