프로젝트:Project3(1)과정 정보(2)학습 열기 로봇은 관절이라는 Joint와 로봇 팔에 해당하는 Arm으로 구성됩니다.그리고 Arm은 Joint을 중심으로 회전 운동을 합니다.이번은 유니티 프로젝트를 통해서, 1축 로봇 팔에 대한 반대 구학을 가상의 유니티 2차원 공간에서 구현하고 봅시다.(3)학습 내용(4)우선 내가 미리 만들어 놓은 유니티 프로젝트 Project2를 엽니다.(5)Project2를 선택하면 다음과 같은 미리 작성된 Project2의 초기 화면이 표시됩니다.(6)Scenes폴더에 가서 Robot1을 복사해서 Robot2를 생성합니다.(7)Scenes폴더에서 오른쪽 클릭하면,[Show in Explorer]를 선택해서 표시되는 팝업 창(Assets폴더)에서[Scenes]폴더를 더블 클릭하면 Robot2.Unity이 생성된 것을 알 수 있습니다.(8)스크립트 폴더 안에 Axis1.cs와 Robot1.cs을 남기고 나머지 파일(Arm1.cs, Robot2.cs등)은 모두 삭제합니다.(9)Arm1개체에는 Arm1.cs가 Attach되고 있었습니다.Arm1.cs스크립트 파일의 삭제에 의한:”스크립트를 로드할 수 없다”내용의 에러 메세지가 표시됩니다.그러므로[Remove Component]을 통하여 오류를 수정합니다.(10)Robot1객체에 Robot1.cs가 Attach되어 있는지를 확인합니다.(11)Robot1.cs코드 내용을 확인합니다.[H]키와[F]열쇠로 Robo1객체를 좌우로 이동시키는 코드입니다.(12)Axis1오브젝트에 Axis1.cs파일이 Attach되어 있는지를 확인합니다.(13)Axis1.cs의 코드도 확인합니다.Axis1를[Q]키와[A]키에서 시계 반대 방향·시계 방향으로 인화하다 코드입니다.(14)우선[F]키와[H]키를 누르고, 객체가 어떻게 움직이는지 관찰합니다.그리고 Robot1과 Arm1이 왜 함께 움직이는가, 객체의 계층 구조를 보면서 생각합시다.2번째로[Q]키와[A]키를 누르면서 Arm1이 어떻게 회전하는지 관찰하고 보겠습니다.그리고 Arm1이 Robot1의 중심을 기준으로 회전하는 이유를 Robot1과 Axis1, 그리고 Arm1의 계층 구조를 통해서 생각하고 보겠습니다.(15)로봇의 모양을 만들어 봅니다.Robot1의 위치를(0,0,0)로, Axis1에 다음과 같이 Joint1을 Circle Object로 추가합니다.그리고 Axis2를 Empty에서 생성하여 위치를(3,0,0)에 위치하여 Axis1의 하위 객체화합니다.(16)Robot2.cs를 다음과 같이 생성합니다.6번 선은 Robot1개체에서 다른 오브젝트(질은 자식 객체)변수를 전역으로 선언하고 각 변수에 게임 객체 참조를 연결(후에 예정) 되면 이로써 이 객체에 대한 tranform컴포넌트에 접근할 수 있게 됩니다.15번 선에서 Axis1의 회전각을 16번 선에서 Axis2의 위치를 Vector3변수인 rot1과 pos2에 각각 대입합니다.(이후 실행 과정에서 확인합니다)Robot2.unityRobot2.cs
프로젝트: Project 3(1) 과정정보(2) 학습열기 로봇은 관절이라는 Joint와 로봇 팔에 해당하는 Arm으로 구성됩니다. 그리고 Arm은 Joint를 중심으로 회전 운동을 합니다. 이번에는 유니티 프로젝트를 통해 1축 로봇팔에 대한 역기구학을 가상의 유니티 2차원 공간에서 구현해 봅시다.(3)학습내용(4) 먼저 제가 미리 만들어 놓은 유니티 프로젝트 Project 2를 엽니다. (5) Project 2를 선택하면 다음과 같은 미리 작성된 Project 2의 초기화면이 나타납니다.(6)Scenes 폴더에 가서 Robot1을 복사하여 Robot2를 생성합니다. (7) Scenes 폴더에서 우클릭하면 [Show in Explorer]를 선택하여 표시되는 팝업창(Assets 폴더)에서 [Scenes]폴더를 더블 클릭하면 Robot 2. Unity가 생성된 것을 알 수 있습니다. (8) 스크립트 폴더 안에 Axis1.cs 과 Robot1.cs 을 남기고 나머지 파일(Arm1.cs , Robot2.cs 등)은 모두 삭제합니다. (9) Arm1 오브젝트에는 Arm1.cs 이 Attach되어 있었습니다. Arm1.cs 스크립트 파일 삭제로 “스크립트를 로드할 수 없는” 내용의 오류 메시지가 표시됩니다. 따라서 [Remove Component]를 통해 오류를 수정합니다.(10) Robot1 오브젝트에 Robot1.cs 이 Attach되어 있는지 확인합니다. (11) Robot1.cs 코드의 내용을 확인합니다.[H]열쇠와 [F] 키로 Robo1 오브젝트를 좌우로 이동시키는 코드입니다. (12) Axis1 오브젝트에 Axis1.cs 파일이 Attach되고 있는지 확인합니다. (13)Axis1.cs 의 코드도 확인합니다. Axis1을 [Q]키와 [A]키로 시계 반대 방향 · 시계 방향으로 인화하는 코드입니다. (14) 먼저 [F]키와 [H]키를 눌러 객체가 어떻게 움직이는지 관찰합니다. 그리고 Robot1과 Arm1이 왜 같이 움직이는지 객체의 계층 구조를 보면서 생각을 해보도록 하겠습니다. 두 번째로 [Q] 키와 [A] 키를 누르면서 Arm1이 어떻게 회전하는지 관찰해 봅니다. 그리고 Arm1이 Robot1의 중심을 기준으로 회전하는 이유를 Robot1과 Axis1 그리고 Arm1의 계층 구조를 통해서 생각해 보겠습니다. (15) 로봇 모양을 잡아볼게요. Robot1의 위치를 (0,0,0)로 하고 Axis1에 다음과 같이 Joint1을 Circle Object로 추가합니다. 그리고 Axis2를 Empty로 생성하여 위치를 (3,0,0)에 위치시키고 Axis1의 하위 객체화 합니다. (16) Robot2.cs 를 다음과 같이 생성합니다. 6번 선은 Robot1 객체에서 다른 객체(질은 자 객체) 변수를 전역에 선언하고 각 변수에 게임 객체 참조를 연결(나중에 예정)하면 이제 이 객체에 대한 tranform 컴포넌트에 접근할 수 있게 됩니다. 15번 선에서 Axis1의 회전각을 16번 선에서 Axis2의 위치를 Vector3 변수인 rot1과 pos2에 각각 대입합니다. (이후 실행에서 확인합니다) Robot2.unityRobot2.cs
(17)Robot1개체에서 이전 attach한 Robot1.cs를 해제하고 새로운 스크립트인 Robot2.cs를 Attach 합니다.그리고 전역 개체 변수인 Axis1과 Axis2의 참조를 매답니다.(18)실행하면 Rot1에 Axis1의 회전각이 표시되고(Rot1.z), Pos2에 Axis2의 위치 좌표치(Pos2.x, Pos2.y)가 표시되는 것으로 나타납니다.(19)1축 로봇 구학은 다음과 같습니다.이 공식에 근거하여 Kinematics1()함수와 InvKinematics1()함수를 만들어 봅시다.(20)Robot2.cs의 코드를 다음과 같이 수정/추가 작성합니다.4번 선은 Cos(), Sin(), PI등을 계산하기 위한 Math라이브러리를 추가하는 전처리문입니다.7번 줄에서 GameObject변수 Arm1을 추가하고 8번 줄에서 Vector3변수 pos2_calc를 추가합니다.20~29번 선은 Kinematics1()함수를 구현한 것입니다.20번 선에서 doubl형 변수 theta_deg을 매개 변수로 받아 22번 선에서 이 변수를 radia값으로 변환하고 doubl형 변수 theta에 대입합니다.24번 선은 Arm1개체의 비늘치를 살피는, Vector3변수 sca에 대입합니다.그리고 이 변수의 x성분을 float형 변수 d에 대입합니다.(25번 선).26번 선과 27번 선은 1축 링크 기구 공식입니다.이를 Vector3형식 변수로 갚겠습니다.그리고 18번 선에서 이 함수를 호출하고 그 결과를 Vector3변수 pos2_calc에 대입합니다.Robot2.unityRobot2.cs
(17)Robot1 객체에서 이전에 attach했던 Robot1.cs 을 해제하고 새 스크립트인 Robot2.cs 을 Attach합니다. 그리고 전역 객체 변수인 Axis1과 Axis2 참조를 연결합니다.(18) 실행해 보면 Rot1에 Axis1의 회전각이 표시되고(Rot1.z) Pos2에 Axis2의 위치좌표값(Pos2.x, Pos2.y)이 표시되는 것을 알 수 있습니다. (19) 1축 로봇 기구학은 다음과 같습니다. 이 공식을 바탕으로 Kinematics 1() 함수와 Inv Kinematics 1() 함수를 만들어 봅시다. (20) Robot2.cs 의 코드를 다음과 같이 수정/추가 작성합니다. 4번 선은 Cos(), Sin(), PI 등을 계산하기 위한 Math 라이브러리를 추가하는 전처리문입니다. 7번 열에서 GameObject 변수 Arm1을 추가하고 8번 열에서 Vector3 변수 pos2_calc를 추가합니다. 20~29번 선은 Kinematics 1() 함수를 구현한 것입니다. 20번 선에서 doubl형 변수 theta_deg를 매개변수로 받아 22번 선에서 이 변수를 radia 값으로 변환하여 doubl형 변수 theta에 대입합니다. 24번 선은 Arm1 객체의 스케일 값을 알아보고 Vector3 변수 sca에 대입합니다. 그리고 이 변수의 x 성분을 float형 변수 d에 대입합니다.(25번 선). 26번 선과 27번 선은 1축 링크의 기구 공식입니다. 이를 Vector 3형 변수로 반환합니다. 그리고 18번 선에서 이 함수를 호출하고 그 결과를 Vector3 변수 pos2_calc에 대입합니다. Robot2.unityRobot2.cs
(21)실행을 해보면 Pos3와 기구학을 통해 계산한 Pos2_calc가 일치하는지 확인합니다. (22)이번에는 역기구학으로, 반대로 로봇의 위치로부터, 조인트의 각도를 계산해 보겠습니다. 다시 Robt2.cs 의 코드를 다음과 같이 수정/추가 작성합니다. Robot2.unityRobot2inv.cs
시스템을 사용합니다.컬렉션.시스템을 사용한다.컬렉션.범용;Unity Engine을 사용;정적시스템을 사용.Math;public class Robot2:MonoBehavior{public GameObjectAxis1, Axis2, Arm1;public Vector3 rot1, pos2, pos2_protocol, rot1_prot;//처음의 프레임 갱신 void Start(){}//Update이 프레임마다 한번 호출하기 전에 Update(){rot1=Axis1.transform.localUlerRangles;pos2=A.position;pos2_module=Kinematic1(rot1.z);JointAngle jointAngle=InvKinematic1(pos2);rot1_module.z=(float)jointAngle.theta1;}(23) InvKinematics() 함수를 다음과 같이 작성합니다(23) InvKinematics() 함수를 다음과 같이 작성합니다(24)실행하고 보면 이것에서 Rot1과 반대 구학을 통해서 계산한 Rot1_calc가 일치함을 확인합니다.(25)다음은 Arm1의 길이 조정을 위한 Arm1.cs의 작성 부분입니다.Z키를 치면 Arm1의 x축 방향의 길이를 키우고 X키를 치면 Arm1의 x축 방향의 길이가 줄어들게 합니다.Arm1의 x축장이 변화하면, Arm1의 중심도 이동해야 하며 Arm1의 첨단에 붙어 있는 Axis2의 위치도 조정합니다.Robot2Prism.unityRobot2InvPrsim.cs(24) 실행해 보면 이제 Rot1과 역기구학을 통해 계산한 Rot1_calc가 일치하는지 확인합니다. (25) 다음은 Arm1의 길이 조정을 위한 Arm1.cs 의 작성 부분입니다. Z키를 치면 Arm1의 x축 방향 길이를 늘리고, X키를 치면 Arm1의 x축 방향 길이가 줄어들도록 합니다. Arm1의 x축 길이가 변화하면 Arm1의 무게중심도 이동해야 하며 Arm1의 끝에 붙어있는 Axis2의 위치도 조정합니다. Robot2Prism.unityRobot2InvPrsim.cs(26)실행 화면입니다.이로써 1축 로봇 팔이 완성했습니다.(27)이제 여기에 목표를 추가하고 보겠습니다.우선 Robot2의 장면을 복사해서 Robot3_1Axis에 이름을 바꿉니다.그리고 Tartet객체를 추가합니다.위치는(3,0,0), 색은 황색으로 합니다.(28)Target.cs을 작성하고 Target객체에 Attach 합니다.이는 4개의 키(H, F, T, G)을 가지고 타깃을 상하 양쪽으로 이동시키는 프로그램입니다.Robot3_1AxisTarget.unityRobot3_1AxisTarget.cs検出された言語がありません。
入力言語を確認してください。(29)実行すると、上記のようにターゲットが動くことが確認できます。 (30) Robot2invPrism.cs をコピーして名前をRobot3_1AxisTarget.csに変えた後、コードを修正してロボットがTargetに追従するようにしてみます。 まず、コードを次のように修正/追加作成します。 (30-1)InveKinematics1()の修正です関節角度InvKinematics1(ベクトル3pos){float x = pos。x; float y = pos。y; double theta1 = Atan2(y, x); JointAngle jointAngle = new JointAngle(); jointAngle。theta1 = rad2(theta1); double d1 = Sqrt(x * x + y * y); jointAngle.d1 = d1; return jointAngle;}class JointAngle{public double theta1,d1;}(30-2)Robot3_1AxisTarget.csの修正(30-2)Robot3_1AxisTarget.csの修正(32) そして、次のようにTargetTracking()関数を作成し、Update()から呼び出します。 このコードに対する解釈は省略するようにします。 実行結果だけお見せします。(32) そして、次のようにTargetTracking()関数を作成し、Update()から呼び出します。 このコードに対する解釈は省略するようにします。 実行結果だけお見せします。(33)실행 결과입니다.