|
| 1 | +# API for Simulating Multi-link System |
| 2 | +Final project of ME314 Machine Dynamics |
| 3 | + |
| 4 | +student: Feiyu Chen |
| 5 | + |
| 6 | +# Contents: |
| 7 | +- [1. Introduction](#1.-Introduction) |
| 8 | +- [2. Files](#2.-Files) |
| 9 | +- [3. API Functions](#3.-API-Functions) |
| 10 | +- [4. Example of Using My Functions](#4.-Example-of-Using-My-Functions) |
| 11 | +- [6. How is This API being |
| 12 | + Generalized](#6.-How-is-This-Api-Being-Generalized) |
| 13 | +- [7. Problems](#7.-Problems) |
| 14 | + |
| 15 | + |
| 16 | +# 1. Introduction |
| 17 | + |
| 18 | +## 1.1 Why I made this API |
| 19 | +It can be a big headache to hardcode the simulation of multi-link system in Mathematica, as it's trivial to type in all formulas and to deal with all kinds of weird bugs. The goal of this project is to reduce such pain by wrapping up an API (> Application Programming Interface) so users/students could build up a simulation by using simple functions. |
| 20 | + |
| 21 | +## 1.2 Intro |
| 22 | + |
| 23 | +The core of the API is a set of functions called "createLink", with Applications of creating links, triangle (polygon), vertices and wall. I made 4 scenes to demonstrate the usage of my API which are stored in "./scenes/". The videos are in current folder. The images are shown here. |
| 24 | + |
| 25 | + |
| 26 | +Figure 1. Four example scenes of multi-link system. |
| 27 | + |
| 28 | + |
| 29 | +## 1.3 How to run |
| 30 | + |
| 31 | +Open this [run_this.nb](run_this.nb). Choose a scene in the sceond cell (you can search the keyword "Choose a scene"). And then run through the whole script. |
| 32 | + |
| 33 | + |
| 34 | +# 2. Files |
| 35 | +## 2.1 run_this.nb |
| 36 | +This is the main file. |
| 37 | + |
| 38 | +## 2.2 scenes/ |
| 39 | +The scenes are stored in "./scenes/". Inside each scene script, there is a only function called "CreateObjects[]". It describes the links that form the simulation. You may change and create your own |
| 40 | + |
| 41 | +## 2.3 lib/ |
| 42 | +This stores 3 library files: [funcs_assist.nb](funcs_assist.nb), [funcs_main.nb](funcs_main.nb), and [funcs_math.nb](funcs_math.nb). They provide the necessary functions and parameters for the main script. They will be loaded when running the "run_this.nb". |
| 43 | + |
| 44 | +# 3. API Functions |
| 45 | +I wrote 5 functions: |
| 46 | + |
| 47 | +### 3.1 createVertex |
| 48 | + |
| 49 | + Create a vertex. |
| 50 | + |
| 51 | + > Application: create a point obstacle, or append a link to it to make a pendulum. |
| 52 | +
|
| 53 | +### 3.2 createLink0DOFpp |
| 54 | + |
| 55 | + Create a link with 0 degrees of freedom (DOF). The "pp" at the end indicates that the inputs are two points "point1" and "point2" with format of 2-vector. |
| 56 | + |
| 57 | + > Application: create a wall, or append it to another link to form a rigid body. See an example in Example 1 of creating polygon. |
| 58 | +
|
| 59 | +### 3.3 createLink0DOFg$\mathbf{\theta}$l |
| 60 | + |
| 61 | + This is same as above for creating a 0 DOF link, except that the inputs are: |
| 62 | + * The starting coordinate's 4x4 matrix $\mathbf{g}$. |
| 63 | + * Relative angle $\theta$. |
| 64 | + * Length of this link $\mathbf{l}$. |
| 65 | + |
| 66 | +### 3.4 createLink1DOFg$\mathbf{\theta}$l |
| 67 | + |
| 68 | + Create a 1 DOF link. The link can rotate around its starting coordinate $\mathbf{g}$. |
| 69 | + |
| 70 | + The inputs "g$\mathbf{\theta}$l" are the same as above, which are used for specifying the starting coordinate, relative angle, and length of this link. |
| 71 | + |
| 72 | + > Application: append this link to a pendulum. For example, turning a double-pendulum into a triple-pendulum. |
| 73 | +
|
| 74 | +### 3.5 createLink3DOFpp |
| 75 | + |
| 76 | + Create a 3 DOF link that can move in $\mathbf{x}$ and $\mathbf{y}$ direction and rotate around its center for angle $\theta$. |
| 77 | + Its inputs are the initial positions of its two vertices. |
| 78 | + |
| 79 | + > Application: creating a free link. Append other 1 DOF links to it to form a flying multi-link. |
| 80 | +
|
| 81 | +# 4. Example of Using My Functions |
| 82 | + |
| 83 | +I will take the scene1 as example and show how to use my API. |
| 84 | + |
| 85 | +Below is a figure of scene1 with annotations of its frames and transformations. |
| 86 | + |
| 87 | + |
| 88 | + |
| 89 | +Figure 2. Scene1 with annoations of frames and transformations |
| 90 | + |
| 91 | + |
| 92 | +The x and y axis of each frame are denoted by straight arrows. There are 3 types of frames/links: |
| 93 | +* <span style="color:red"> *Red frame* </span> is for 3-DOF link that has variables $\mathbf{x}$, $\mathbf{y}$, and $\mathbf{theta}$. |
| 94 | +* <span style="color:green"> *Green frame* </span> is for 1-DOF link, which has variable $\mathbf{theta}$ and can rotate around a certain pivot. |
| 95 | +* <span style="color:gray"> *Gray frame* </span> is for 0-DOF link, whose two vertices are fixed in a certain frame. |
| 96 | + |
| 97 | +The transformations between different frames are denoted by curved arrows in <span style="color:cyan"> **cyan**</span>. These transformations connect up several links to form an object. |
| 98 | + |
| 99 | +There are 5 groups of links in the figure: |
| 100 | +1. A pentagon (DOF=3) |
| 101 | +2. A 2-link pendulum (DOF=2) |
| 102 | +3. A 1-link pendulum (DOF=3, height of the left vertex is fixed) |
| 103 | +4. A 1-link wall (DOF=0) |
| 104 | +5. Four walls around the main objects (DOF=0) |
| 105 | + |
| 106 | +The pseudo code for creating these 5 groups of links are as follows: |
| 107 | + |
| 108 | +* 1 . Pentagon (3 DOF) |
| 109 | + > createLink3DOF |
| 110 | +createLink0DOF |
| 111 | +createLink0DOF |
| 112 | +createLink0DOF |
| 113 | +createLink0DOF |
| 114 | + |
| 115 | +* 2 . Two-link pendulum (2 DOF) |
| 116 | + > createVertex |
| 117 | +createLink1DOF |
| 118 | +createLink1DOF |
| 119 | + |
| 120 | +* 3 . One-link with constrained height (3 DOF + 1 Constraint) |
| 121 | + > createLink3DOF |
| 122 | +addConstraint[y==0] |
| 123 | + |
| 124 | +* 4/5 . Walls (0 DOF) |
| 125 | + > createLink0DOF |
| 126 | +createLink0DOF |
| 127 | + |
| 128 | +After creating these links, you can simply run the main file and see the animation. |
| 129 | + |
| 130 | +## 5. Calculation of EL-eqs and Impacts |
| 131 | + |
| 132 | +### 5.1 Kinetic and Potential Energy |
| 133 | +Suppose a link has length $\mathbf{l}$. Then I assume its mass to be $\mathbf{l}$ and inertia to be $\mathbf{l^2}$. The generalized 6x6 body mass M is then obtained. |
| 134 | + |
| 135 | +For each link, I compute the 4x4 matrix representation $\mathbf{g}$ of its center frame. Then calculate the body screw velocity $\mathbf{V}$ using $\mathbf{g}$ and $\mathbf{dg/dt}$. Then the kinetic energy is $\frac{1}{2}\mathbf{V^T M V}$. |
| 136 | + |
| 137 | +### 5.2 Constraint and External Force |
| 138 | + |
| 139 | +These two elements can be easily added up to the EL-eqs. |
| 140 | + |
| 141 | +In scene1.nb, I add a constraint to the link at right up corner. I fixed its height by the code below, where "IdxPBack" refers to the "Point at Back side", and "[[2]]" refers to "y" ("[[1]]" refers to "x"). One internal problem of constraint is that its only added to the velocity, not displacement. See the Section "Problems" for more details. |
| 142 | +> addConstraint[linki[[IdxPBack]][[2]] == 0]; |
| 143 | +
|
| 144 | +The external forces are set in this sentence: |
| 145 | +> externalForces = ConstantArray[0, nVars]; |
| 146 | +
|
| 147 | +### 5.3 Detecting Impacts |
| 148 | + |
| 149 | +The impact happens when **one link's vertex** goes through **another link's edge**. The two links should also from different groups. |
| 150 | + |
| 151 | +The impact conditions are defined in the function **"SetUpImpactEvents"** in **"lib/funcs_main.nb"**. |
| 152 | + |
| 153 | +For determining whether a vertex is inside the edge, I wrote two different methods/functions. In the current version, the second function is adopted: |
| 154 | + |
| 155 | +1. checkInObstacle1: checks the distance between vertex and edge. If the distance is small, then vertex is in edge. |
| 156 | +2. checkInObstacle2: checks the sign of distance between vertex and edge. A change of sign means the vertex goes through the edge. |
| 157 | + |
| 158 | +(Meanwhile, whether the projection of vertex is on edge is also considered.) |
| 159 | + |
| 160 | +### 5.4 Impact Update |
| 161 | + |
| 162 | +The logic of my code for impact detection looks like this: |
| 163 | + |
| 164 | +``` |
| 165 | +Loop{ |
| 166 | + While(no impact && t!=t_end{ |
| 167 | + NDSolve |
| 168 | + } |
| 169 | + if(impacts){ |
| 170 | + impact update for each impact |
| 171 | + }else{ |
| 172 | + break |
| 173 | + } |
| 174 | +} |
| 175 | +``` |
| 176 | + |
| 177 | + |
| 178 | +# 6. How is This API being Generalized |
| 179 | + |
| 180 | +* How to deal with the varying total DOF |
| 181 | + I push variables into a list, and use vector/matrix operation to compute all equations. It requires some understanding of all the formulas. |
| 182 | + |
| 183 | +* How to detect impact |
| 184 | + Every time adding a new link, I push its **edge** into a list, and push its 2 **vertices** into another list. When detecting impacts, I go through these two lists, and check if a **vertex** is near an **edge**. (The vertex and edge that have a same group ID will be ignored.) |
| 185 | + |
| 186 | + |
| 187 | + |
| 188 | +# 7. Problems |
| 189 | +### **Not Detecting Some Impacts** |
| 190 | + At some occasions, the vertex might go through the edge. The cause is that the object's velocity is too large, or the integration step length is too large. Currently, I didn't implement any advanced techinques to go back and forth to check the exact impact time. |
| 191 | + |
| 192 | + So you might need to reduce the integration step length, or make your scene smaller (thus less potential energy and a smaller max speed). |
| 193 | + |
| 194 | +### **Slow Computing** |
| 195 | + When the total DOF<10, links<15, step_size=0.001, simulation_time=15s, it takes about 3 minutes to compute all motions. Thus, the DOF and links cannot be too many, or it will cost too much time to compute impacts and do NDSolve. |
| 196 | + |
| 197 | +### **Be Cautions with Constraint** |
| 198 | + When applying constraint to a configuration variable, we must make sure that this variable won't move perpendicular to the constraint surface. Two cases (which are not subject to the solution of EL-eqs) can cause problem of making total energy not conserved: |
| 199 | + |
| 200 | + 1. Wrong initial velocity. |
| 201 | + 2. Impacts. |
| 202 | + |
| 203 | + The reason is that we are actually not applying constraint $\mathbf{\phi}$. Instead, we use $\mathbf{d\phi /dq}$ and $\mathbf{d^2\phi /dt^2}$ for solving EL-eqs. |
| 204 | + |
| 205 | +### **No Varying Constraint** |
| 206 | + I didn't add varying constraint in this project. But I do make an analysis of how to do it below: |
| 207 | + |
| 208 | + Consider a chair on the floor. Under my current scheme, the chair will keep on impacting with the floor and make the simulation slow and inaccurate. |
| 209 | + |
| 210 | + What I'm supposed to add: If the speed of the contact point after impact is very small, I should add a constraint to it to make this point fix on the floor. Then, do the Solve again, and keep on NDSolve. Then, if at some time the constraint force is zero or changes direction, I should remove this constraint. |
0 commit comments