此博客用于记录与分享自己在使用mathmatica进行机械运动仿真的所学所作。非常简单,有手就行。
基于Mathematica的机器人仿真环境(机械臂篇)_自己搭建机器人仿真软件-优快云博客
此文给我莫大帮助,本文内容是此文的部分展示。
项目源于我对五轴打印机的兴趣:通过赋予传统3D打印机打印件额外两个旋转自由度,可以大幅增加(在没有支撑的情况下)能打印的造型范围。尤其是以旋转对称为主要特征的模型。
本着没有难度也要增加难度的想法,我在参考了open5x的3d打印机构型后从头造了一个打印机(截至目前2024.1.6没有实现全部功能)。下面进入正文:
在完成打印机建模后,为了减少仿真所需计算量,需要对真实模型瘦身并转换为STL格式(使用solidworks转换时记得勾选“不要转换STL输出数据到正的坐标空间”),最终简化到了6个部件,按1~6的顺序命名,分别对应框架,以及x、y、z、u、v五个自由度所需的五个活动部件。
代码如下
SetDirectory["C:\\Users\\Mr.H\\Desktop\\mmaprint"]
partsName = {"1.stl", "2.stl", "3.stl", "4.stl", "5.stl", "6.stl"};
robotPartsGraphics = Import[#, "Graphics3D"] & /@ partsName;
robotParts = robotPartsGraphics[[;; , 1]];
robotParts =
Table[GraphicsComplex[robotParts[[i, 1]], robotParts[[i, 2]]], {i,
6}];
colors = {Gray, Cyan, Orange, Green, Magenta, Yellow};
robotPartsColored = Transpose@{colors, robotParts};
Graphics3D[robotPartsColored]
S输出效果如下:
程序中的robotParts[[i, 1]]、robotParts[[i, 2]]分别表示第i个3d模型的所有点和三角形面。通过对这些点和面的移动和旋转,得到移动和旋转整体模型的效果。数据格式中并不存在robotParts[[i, 3]]
接下来就是使用GraphicsComplex(和Manipulate),将不同的平移和旋转矩阵与每个部件的坐标相乘,实现平移或者旋转的(动态)效果。
先将第六个部件初始位置调整一下(导出STL模型时疏忽了)。
newpart61 = GraphicsComplex[(\!\(\*
TagBox[GridBox[{
{".010958077"},
{".00415"},
{
RowBox[{"-", ".16525"}]}
},
GridBoxAlignment->{
"Columns" -> {{Center}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.5599999999999999]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}}],
Column]\)) + # & /@ robotParts[[6, 1]], robotParts[[6, 2]]];
Graphics3D[{robotParts[[1]], newpart61}]
Manipulate[
Graphics3D[{robotParts[[1]],
GraphicsComplex[RotationMatrix[x, {0, 0, 1}].# & /@ newpart61[[1]],
newpart61[[2]]]}], {x, 0 Degree, 360 Degree}]
在每个模型的名字后面我用数字区分变换前后的模型,例如61就是6经过一次变换,接下来62就是61再经过一次变换后的模型。
运行结果如下:
ps:可以通过RotationMatrix[u, {1, 0, 0}] // MatrixForm得到相应的具体变换矩阵
接下来就是对每个部件套矩阵了
<
newpart51 = GraphicsComplex[(\!\(\*
TagBox[GridBox[{
{".157658"},
{".00415"},
{
RowBox[{"-", ".12425"}]}
},
GridBoxAlignment->{
"Columns" -> {{Center}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.5599999999999999]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}}],
Column]\)) + # & /@ robotParts[[5, 1]], robotParts[[5, 2]]];
newpart52[x_] :=
GraphicsComplex[RotationMatrix[x , {1, 0, 0}].# & /@ newpart51[[1]],
newpart51[[2]]];
newpart62[v_, u_] := GraphicsComplex[\!\(\*
TagBox[
RowBox[{
TagBox[
RowBox[{"(", "", GridBox[{
{"1", "0", "0"},
{"0",
RowBox[{"Cos", "[", "v", "]"}],
RowBox[{"-",
RowBox[{"Sin", "[", "v", "]"}]}]},
{"0",
RowBox[{"Sin", "[", "v", "]"}],
RowBox[{"Cos", "[", "v", "]"}]}
},
GridBoxAlignment->{
"Columns" -> {{Center}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.7]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}}], "", ")"}],
Function[BoxForm`e$,
MatrixForm[BoxForm`e$]]], ".",
RowBox[{"(", "", GridBox[{
{
RowBox[{"Cos", "[", "u", "]"}],
RowBox[{"-",
RowBox[{"Sin", "[", "u", "]"}]}], "0"},
{
RowBox[{"Sin", "[", "u", "]"}],
RowBox[{"Cos", "[", "u", "]"}], "0"},
{"0", "0", "1"}
},
GridBoxAlignment->{
"Columns" -> {{Center}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.7]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}}], "", ")"}]}],
Function[BoxForm`e$,
MatrixForm[BoxForm`e$]]]\).# & /@ newpart61[[1]], newpart61[[2]]];
Manipulate[
Graphics3D[{LightGray, robotParts[[1]],
Blue, GraphicsComplex[(\!\(\*
TagBox[GridBox[{
{"x"},
{"0"},
{"0"}
},
GridBoxAlignment->{
"Columns" -> {{Center}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.5599999999999999]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}}],
Column]\)) + # & /@ robotParts[[2, 1]], robotParts[[2, 2]]],
Red, GraphicsComplex[(\!\(\*
TagBox[GridBox[{
{"x"},
{"y"},
{"0"}
},
GridBoxAlignment->{
"Columns" -> {{Center}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.5599999999999999]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}}],
Column]\)) + # & /@ robotParts[[3, 1]], robotParts[[3, 2]]],
Green, GraphicsComplex[(\!\(\*
TagBox[GridBox[{
{"0"},
{"0"},
{"z"}
},
GridBoxAlignment->{
"Columns" -> {{Center}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.5599999999999999]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}}],
Column]\)) + # & /@ robotParts[[4, 1]], robotParts[[4, 2]]],
Magenta, GraphicsComplex[(\!\(\*
TagBox[GridBox[{
{
RowBox[{"-", ".157658"}]},
{
RowBox[{"-", ".00415"}]},
{
RowBox[{".12425", "+", "z"}]}
},
GridBoxAlignment->{
"Columns" -> {{Center}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.5599999999999999]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}}],
Column]\)) + # & /@ newpart52[u ][[1]], newpart52[u ][[2]]], Yellow,
GraphicsComplex[(\!\(\*
TagBox[GridBox[{
{
RowBox[{"-", ".157658"}]},
{
RowBox[{"-", ".00415"}]},
{
RowBox[{".12425", "+", "z"}]}
},
GridBoxAlignment->{
"Columns" -> {{Center}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.5599999999999999]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}}],
Column]\)) + \!\(\*
TagBox[
RowBox[{"(", "", GridBox[{
{"1", "0", "0"},
{"0",
RowBox[{"Cos", "[", "u", "]"}],
RowBox[{"-",
RowBox[{"Sin", "[", "u", "]"}]}]},
{"0",
RowBox[{"Sin", "[", "u", "]"}],
RowBox[{"Cos", "[", "u", "]"}]}
},
GridBoxAlignment->{
"Columns" -> {{Center}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.7]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}}], "", ")"}],
Function[BoxForm`e$,
MatrixForm[BoxForm`e$]]]\).\!\(\*
TagBox[
RowBox[{"(", "",
TagBox[GridBox[{
{"0.14669992299999998`"},
{"0.`"},
{"0.04100000000000001`"}
},
GridBoxAlignment->{
"Columns" -> {{Center}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.5599999999999999]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}}],
Column], "", ")"}],
Function[BoxForm`e$,
MatrixForm[BoxForm`e$]]]\) + # & /@ newpart64[u, v][[1]],
newpart62[u, v][[2]]]
}], {x, 0, .12}, {y, 0, .12}, {z, 0, .12}, {u, 0 Degree,
90 Degree }, {v, 0 Degree, 90 Degree }]
>
效果如下: