Germany
Asked — Edited

Digital Clone Rover Roli

maybe someone can use it....

can be used with the standard project of Roli, just create an EZ-Script and run it:

$go=true
repeatwhile($go) 
$strSend = "D9@" + GetServo(d9) + ";D10@" + GetServo(d10) 
$strSend = $strSend + ";D19@" + GetServo(d19) + ";D18@" + GetServo(d18) + ";D17@" + GetServo(d17) + ";D16@" + GetServo(d16)
$strSend = $strSend + ";D15@" + GetServo(d15) + ";D14@" + GetServo(d14) + ";D13@" + GetServo(d13) + ";D12@" + GetServo(d12)
SendUDP("127.0.0.1", 11000, $strSend)
Sleep(100)
endrepeatwhile

Here is the program for download: digitalCloneRoverRoli.zip and here the Unity project data to tinker around with yourself: Unity.zip

Have fun ...

24.07.22 Update in Post #17 -  Version with moving Rover ....

.


ARC Pro

Upgrade to ARC Pro

ARC Pro is your gateway to a community of like-minded robot enthusiasts and professionals, all united by a passion for advanced robot programming.

PRO
Synthiam
#1  

You are doing so well with Unity! I'm incredibly impressed. I always thought it would be neat to have a virtual robot app like that where you could program a robot without actually owning the robot. And you did it! Imagine how awesome it would be if someone could design their robot with the ez-bit parts! Have you thought of making something like that? I'd sell it for you!

PRO
Germany
#2  

thanks, I really appreciate it. Exactly this is the point, i made it exclusively with the stl fils from here, nothing is made by myself. I'm also a complete novice with unity but it's so easy. I've been thinking about doing a tutorial, are you interested? In short, assemble the stl files in tinkercad and export them as obj, import them into unity .... Whereby my c# and also e.g. the string in EZ-Script with UDP are definitely not what they should be, I am aware of this but it works :-)

PRO
Synthiam
#3  

A tutorial would be neat! I think it would be really useful for schools that can’t afford robot hardware. They could program a robot without the high cost.

i guess you could also put the robot in a 3D world and have it move too? That’s so neat!

PRO
Germany
#4   — Edited

hmm, I have to think about how to get that visualized, e.g. what if the robot reaches the limits of the world etc... I'm trying to create a tutorial, as a start, based on what I've done so far. this would be my first ever created tutorial :-)

Edit1: quick search has shown, should also be easily possible, keyword "infinite world" https://www.youtube.com/watch?v=f9uueg_AUZs https://www.youtube.com/watch?v=cUAprBYS_0Q

Edit2: hmm, another idea that just occurred to me, how about a free asset in unity with all ez-bit parts.... .

PRO
Synthiam
#5  

Oh a free asset with ezbits is brilliant. And then some code attached which allows moving the parts like you did.

I can write a class that acts as an ezb. So you actually connect ARC to it as an ezb! Wow that would be so cool.

I think by making the objects rigid that the works could have walls. Or a room. Or what ever the world is. Because there’s a number of free 3D world assets that can be downloaded from the unity store

PRO
Germany
#6   — Edited

Exactly, this should all be possible with relatively little effort.

I still have a problem that I haven't been able to solve so far, so you can certainly contribute a solution with your knowledge.

The "servo models" in Unity are at 90 degrees but the axes in Unity are of course at different degree positions, also in Unity you sometimes have negative values. I need a function that transforms the servo positions from ARC into the Unity world, here is the code from Unity, I calculated it with a try, but there should be a function for it:

if (servo[0] == "D19")
   AxisRightShoulder_Y_D19.transform.localEulerAngles = new Vector3(0, (neuPos - 180), 0);

if (servo[0] == "D18")
    AxisRightElbow_Y_D18.transform.localEulerAngles = new Vector3(-180, (neuPos - 180), 0);

if (servo[0] == "D17")
   AxisRightWrist_Y_D17.transform.localEulerAngles = new Vector3(-180, (neuPos * -1), 0);

if (servo[0] == "D16")
   AxisRightGripper_right_Claw_X_D16.transform.localEulerAngles = new Vector3(((neuPos * -1) * -1), 0, -90);
    AxisRightGripper_left_Claw_X_D16.transform.localEulerAngles = new Vector3((neuPos * -1) - 180, 0, -90);

This Parts:

neuPos - 180 or neuPos * -1 or neuPos * -1 or (neuPos * -1) * -1 or (neuPos * -1) - 180 etc.

right Elbow in Unity

User-inserted image

right Shoulder in Unity

User-inserted image

Do you understand what I mean ?

The UDP part would also have to be rewritten or replaced in Unity, I found something on the Internet and used it, but this is definitely too much of what we actually need, but you already have everything ready anyway Server/Client Code,

I uploaded the two unity scripts: Scripts.zip

.

PRO
Synthiam
#7  

A mapping function is useful for that.


    public static float Map(float value, float inputMin, float inputMax, float outputMin, float outputMax) {

      value = System.Math.Min(value, inputMax);
      value = System.Math.Max(value, inputMin);

      return (value - inputMin) / (inputMax - inputMin) * (outputMax - outputMin) + outputMin;
    }

You can therefore do something like...


var unityPos = Map(70, 1, 180, -1, 1);

That will map the value 70 (within the range of 1-180) to a relative value within the range of -1 to +1

PRO
Germany
#8   — Edited

perfect, exactly what I mean. I didn't know what to look for (keyword). Works great, one step further...


    void Update()
    {
        foreach (var message in connection.getMessages())
        {
           servoSet = message.Split(';');

            for (int i = 0; i < servoSet.Length; i++)
            {
                servo = servoSet[i].Split('@');
                neuPos = float.Parse(servo[1]);

                if (servo[0] == "D9")
                    AxisNeckVertical_Y_D9.transform.localEulerAngles = new Vector3(-180, Map(neuPos, 1, 180, 0, -180), 0);
                
                if (servo[0] == "D10")
                    AxisNeckHorizontal_Y_D10.transform.localEulerAngles = new Vector3(0, Map(neuPos, 1, 180, -90, 90), 0);
                

                if (servo[0] == "D19")
                    AxisRightShoulder_Y_D19.transform.localEulerAngles = new Vector3(0, Map(neuPos, 1, 180, -180, 0), 0);
                        
                if (servo[0] == "D18")
                    AxisRightElbow_Y_D18.transform.localEulerAngles = new Vector3(-180, Map(neuPos, 1, 180, -180, 0), 0);
                
                if (servo[0] == "D17")
                    AxisRightWrist_Y_D17.transform.localEulerAngles = new Vector3(-180, Map(neuPos, 1, 180, 0, -180), 0);
                
                if (servo[0] == "D16")
                    AxisRightGripper_right_Claw_X_D16.transform.localEulerAngles = new Vector3(Map(neuPos, 1, 180, 0, 180), 0, -90);
                    AxisRightGripper_left_Claw_X_D16.transform.localEulerAngles = new Vector3(Map(neuPos, 1, 180, 180, 0), 0, -90);
                
                
                if (servo[0] == "D15")
                    AxisLeftShoulder_Y_D15.transform.localEulerAngles = new Vector3(0, Map(neuPos, 1, 180, 0, 180), 0);
                
                if (servo[0] == "D14")
                    AxisLeftElbow_Y_D14.transform.localEulerAngles = new Vector3(-180, Map(neuPos, 1, 180, -180, 0), 0);
                
                if (servo[0] == "D13")
                    AxisLeftWrist_Y_D13.transform.localEulerAngles = new Vector3(-180, Map(neuPos, 1, 180, 0, -180), 0);
                
                if (servo[0] == "D12")
                    AxisLeftGripper_right_Claw_X_D12.transform.localEulerAngles = new Vector3(Map(neuPos, 1, 180, 0, 180), 0, -90);
                    AxisLeftGripper_left_Claw_X_D12.transform.localEulerAngles = new Vector3(Map(neuPos, 1, 180, 180, 0), 0, -90);
            }
        }
    }

    public static float Map(float value, float inputMin, float inputMax, float outputMin, float outputMax)
    {
        value = System.Math.Min(value, inputMax);
        value = System.Math.Max(value, inputMin);

        return (value - inputMin) / (inputMax - inputMin) * (outputMax - outputMin) + outputMin;
    }

.