Simple Robot Arm: Making 3 objects rotate in sequence - PLEASE HELP

You can download the project files by clicking on this link:
http://www.creativedesigndigital.co.uk/roboarm.zip

I have three objects:

  • top cylinder
  • main arm
  • secondary arm
  • scoop

They are in a hiierachy as follow:
topcylinder > mainarm > secondaryarm

When I push a key, i wish for all object to go through a series of simple roational movements and finish in a pre defined position, smoothly with some easing in and easing out of the rotation.

For exampe, the topcylinder will rotate 200 degrees, the mainarm will then rotate 45 degrees and at the same time, the secondaryarm will rotate to maintain a level orientation in space.


Here is my Script:
//Speed factors for each of the object - THESE DONT SEEM TO WORK…
var topCylinder_speed = 5.0;
var mainArm_speed = 5.0;
var secondaryArm_speed = 5.0;

//These variables monitor the angle of the objects for the ‘if’ statements in the 'Update() function…
var topCylinder_base_angle = 0.0;
var mainArm_base_angle = 0.0;
var secondaryArm_base_angle = 0.0;

//I intended to use these in the if statements but they dont work for some reason…
var base_angle_min = -45.0;
var base_angle_max = 200;

//Initializing the rotation amounts - NOT REALLY SURE IF THESE ARE RIGHT…
var topCylinderRotation = 0.0;
var mainArmRotation = 0.0;
var secondaryArmRotation = 0.0;

//Initialising the variable to hold the name of the seconaryarm. This is so we can find it for rotating it (see ‘Start ()’ and ‘defineObjectNamesGlobally()’ functions…
var secondaryArmName;

//On Start this function passes the name of the ‘secondaryarm’ object out to another function so that we can make it accessible through the Update() function…
function Start () {
var secondaryArmNameID = GameObject.Find(“secondaryarm”);
defineObjectNamesGlobally(secondaryArmNameID);
//Debug.Log("secondaryArmNameID: "+secondaryArmNameID);
}

//'secondaryArmName is set to the value obtained by the ‘GameObject.Find()’ function. We had to do it this way since Unity required the the ‘Game.Find()’ function be run from within the ‘Start()’ function…
function defineObjectNamesGlobally(secondaryArmNameID){
secondaryArmName = secondaryArmNameID;
//Debug.Log("secondaryArmName: "+secondaryArmName);
}

//Uses the data to rotate the objects when the key is pressed…
function Update () {

///Not sure if this is the best way to go about it, I dont fully understand…
topCylinderRotation = Time.deltaTime * topCylinder_speed * 20;
mainArmRotation = Time.deltaTime * mainArm_speed * 20;
secondaryArmRotation = Time.deltaTime * secondaryArm_speed * 20;

if (Input.GetKey(“s”)) {
//begin rotation of topcylinder… i find these angles all a but wild and unpredicatble… I would like to also make it slowly and smoothly ease in and out…
if (topCylinder_base_angle >= -200.0) {
transform.Rotate(0, topCylinderRotation, 0);

//Updating the rotational angle…
topCylinder_base_angle = topCylinder_base_angle - topCylinderRotation;
} else {
//Begin extending the mainarm once the cylinder reaches its full rotation… I would like to smooth these out…

if (mainArm_base_angle >= -45.0) {
transform.Find(“mainarm”).Rotate(0, mainArmRotation *-1, 0);
}

//This didnt work correctly but does now, the secondary arm used too shoot off to a bizzar angle!.. I want it to remain 90 degrees to the horizon…
if (secondaryArm_base_angle >= -45) {
//using the data obtained from the Start() function… (was not sure how to go to the second child in a hierachy)…
secondaryArmName.transform.Rotate(secondaryArmRotation, 0, 0);
}
mainArm_base_angle = mainArm_base_angle - mainArmRotation;
secondaryArm_base_angle = secondaryArm_base_angle - secondaryArmRotation;
}

}
Debug.Log(secondaryArm_base_angle);
}


Ideally, i’d rather be able to define a target point in space for the scoop to get to and the rest to just follow if that makes sense. For example in the scene their is a sphere, i’d like it to look for where that is and head for it. I also want it to be able to reverse back through the motions to go back ‘home’. Also, I’d like to add smoothing to all of the movements.

Thanks for all your help for this in advance!

Best,
Jonathan. :slight_smile:

Take a look at the Mathf.MoveTowardsAngle method

On another note, In your startup, rather than using GameObject.find use transform.find. This is a small thing but the difference is the transform.find only looks through the local hierarchy (Children of the transform) rather than all Gameobjects.

Hey there thanks for that! Just trying it out.

How do I ensure that it rotates the wy I wish it too?

For example, asking it to rotate to 270 degrees cause it to rotate CCW where as asking it to rotate to 90 causes it to rotate CW.

In other words, its picking the shortest route!

J.

Hi Jonathan,

Looked at your project,

What you need is iTween, this is a library allowing you to do animate object in a very convenient and powerful way.

http://itween.pixelplacement.com/gettingstarted.php

There are actually few questions that needs to be asked before the best solution is picked:

– what is your ultimate goal? if you actually whish to implement some kind of seeking system so that the robot will reach the sphere, then a different approach is needed, if this is just for a simple static anim and the sphere will not move, then using itween is the way to go.

– Is it a project you use for learning or the base for a real project with many more robots, and things going on? if for a real project, you will need to set up more robust scripts that will allow you to reuse in different robots and configurations.

Allow me few days before I get back to you with a version of your robot working with itween.
Bye,

Jean

@Jonathan: annoyingly, if you want to turn through a reflex angle (ie, greater than 180º) you need to split it into two turns, each less than 180º.

Hi Jonathan,

Ok, I have worked on your robot arm, you can download the project ( scene robotarm_v2 ) here:

http://dl.dropbox.com/u/17356625/Unity/projects/roboarm.zip

I built an arm actuator script that can be controlled by the user or by script.

You can now control your robot with 3 inputs ( horizontal, vertical, and a third axes if you have a joystick or simply “r” and “t”). Look in the input settings for more infos.

I made the arm actuator quite flexible enough so that you can apply it to any robot, since it’s a behavior, you attach this to each and every arms of your robot, define the axis it should rotate around, its speed, its limits and what input controls this arm.

Being a technical subject, I went into my preferred way of scripting such pivot, that is I control myself the current value, and limits, that way I do not have any problems with angles, it might have some flaws, but not when used for its purpose ( unless I missed something :slight_smile: )

To animate the robot arm, press space bar, and it will move automatically ( during that time you can’t control the arm via user input), press space bar again to make the robot go back to its resting position. The script is using iTween excellent library, so you have full control over how the animation goes, you can define how long it will take, how fast it should go, if there is any delay, and what easing to apply. I went for a default set up but obviously, this will need to be adjusted to your liking and requirements.

The next step is to compute automatically the robot arms transforms, using simple inverse kinematics, Your robot is not complicated and a simple 2 limb IK combined is enough to let the robot compute itself where to go and even follow moving targets. If you need help on that too, don’t hesitate.

If you have any questions, don’t hesitate, I hope you will find it useful :slight_smile:

Bye,

Jean

Jean,

Sorry for the late reply! Have been swamped! Now about to send you a PM sir.

Best.

Jean -
Your iTween usage in the above example was very helpful. I’m working on a similar item (a digitizing arm simulator), where there is a fixed/known (“0,0,0”) start position, followed by pairs of rotation joints per arm (ie. base ->jointx1->jointy1-> arm1 ->jointx2->jointy2 ->arm2 ->jointx3->jointy3-> arm3 ->jointx4->jointy4-> scoop.) Joints of x and y type are orthogonal to each other, where “x” is axial rotation and “y” is radial rotation of the arm.
Working out how to model and implement the scripts from your example I think I can figure out, however given the inputs of joint angles from the user, (8 angles), the fixed origin of (0,0,0), the known lengths of the arms (as they will be modeled) —the question:
Can iTween return the (world/global) position of the last element (scoop) in x,y,z co-ordinates?
I’ve followed a variety of variables in debug mode, but none of the transform values track (at all).

I realize this is a FK problem, which are typically “easier to solve” than inverse, and have worked this out using lots of matricies and Denavit transforms on another system (and the grey cells doing that are too many!), but it looks like the physics of Unity may be a nice upgrade.

(and apologies for hijacking a solved thread).

Kindest regards,

Ted.

Hi Ted,

Ok. tracking is not done with iTween, you track the transform of the gameObject directly, that’s it. when iTween has finished, simply store the transform or extract the actual angle you need for each arms, that will be the way for you to know the current position and return to it from another robot state.

BUT :slight_smile: with my scripts, you would actually only need to store the angle value and not care about the transform at all.

BUT BUT… What you actually want is the position of the tip of your digitizer, and for this, you simply need to query for the position of that gameObject ( provided it’s pivot is actually located at the tip, else attach an empty gameObject to that tip and position it to be at the exact position os the tip and use that dummy instead to know the current point being digitized). When you ask for the position of a transform, it is in world coordinates, so you have a direct access to what you are looking for basically.

If I am on the wrong path, can you clarify?

Bye,

Jean

Jean - actually that was quite it - for a silly reason (I was in Debug mode, not Normal inspector) - and it was showing the local transform, not the global. As I was testing portions of script, I had also commented out the procedural variables and was depending on strictly what the inspector was showing me. So much for common sense! Darn!

Anyways, both the simple kins by parenting and the ITween portion are working exactly as expected.

Thanks!

Ted.

Guys, great code! I’ve been playing around with this and arduino to move an actual robotic claw…i was wondering, how hard is it to translate the code you guys developed to C#, anything in particular you would suggest me to look at?

My post:
http://forum.unity3d.com/threads/131579-Unity-Arduino-for-multiple-inputs-(pushbuttons-slider-imu-board)-codes-attached?p=888361#post888361

Again, great work :smile:

My Rov Simulation
Windows x86

Windows x64
http://www.mediafire.com/?2nmqjkm6k8bgwjs

see this if help
i have small problem with overlapping between every part