# Stewart Platform

Posted 6 years ago
9551 Views
|
35 Replies
|
1 Total Likes
|
 Hi, I downloaded Stewart Platform demo and I changed Long demonstration motion plan as follows: demoMotionPlan = Block[{dx = 0.05, d\[Theta] = 10 \[Degree]}, { {0, 0, 0, 0, 0, 0}, {0, dx, 0, 0, 0, 0}, {0, dx, 0, d\[Theta], 0, 0}, {0, dx, 0, 0, 0, 0}, {0, dx, 0, -d\[Theta], 0, 0}, {0, dx, 0, 0, 0, 0}, {0, dx, 0, 0, d\[Theta], 0}, {0, dx, 0, 0, 0, 0}, {0, dx, 0, 0, -d\[Theta], 0}, {0, dx, 0, 0, 0, 0}, {0, dx, 0, 0, 0, d\[Theta]}, {0, dx, 0, 0, 0, 0}, {0, dx, 0, 0, 0, -d\[Theta]}, {0, dx, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} } ]; Mathematica generates a file called PlatformPath. Only first and the third angle is calculaced correctly. Attachments:
35 Replies
Sort By:
Posted 6 years ago
 maybe inverse kinematics formula is not correct:The "pose" of the moveable platform is defined by 6 coordinates {x,y,z,[Theta],[Phi],[Tau]}. The position of the center of the platform is {x,y,z}. The normal vector pointing upwards out of the platform points in the direction {[Theta],[Phi]} in spherical coordinates. The rotation of the platform about the normal vector is the angle [Tau]. PoseLegEndpoints[{x_, y_, z_, \[Theta]_, \[Phi]_, \[Tau]_}] := Table[Composition[ TranslationTransform[{x, y, z} + {0, platformHeight, 0}], RotationTransform[{{0, 1, 0}, {Sin[\[Theta]] Cos[\[Phi]], Cos[\[Theta]], Sin[\[Theta]] Sin[\[Phi]]}}], RotationTransform[\[Tau], {0, 1, 0}]][p], {p, relativePlatformPoints}] please help
Posted 6 years ago
 If we give some values to platformHeight and relativePlatformPoints, and change the {0, platformHeight, 0} to {0, 0,platformHeight} platformHeight=1; relativePlatformPoints:=Table[{Cos[\[Theta]],Sin[\[Theta]],0},{\[Theta],Range[0,5]/6 2Pi}] PoseLegEndpoints[{x_,y_,z_,\[Theta]_,\[Phi]_,\[Tau]_}]:= Table[ Composition[ TranslationTransform[{x,y,z}+{0,0,platformHeight}], RotationTransform[{{0,1,0}, {Sin[\[Theta]] Cos[\[Phi]], Cos[\[Theta]],Sin[\[Theta]] Sin[\[Phi]]}}], RotationTransform[\[Tau],{0,1,0}]][p], {p,relativePlatformPoints} ] ListPlot3D[PoseLegEndpoints[{0, 0, 0, 0, 0, 0}] // N, PlotRange -> {{-1, 1}, {-1, 1}, {-1, 2}}] This appears to work. But it needs thorough checking.EDIT:After playing around with this, later on, it seems to still need some work. Theta and phi were not working in the above, so I put them in separate RotationTransforms. The plot looks OK now. But it still needs checking. I'm not very experienced with these transformations, although I have had a lot of experience with Stewart platforms. PoseLegEndpoints[{x_,y_,z_,\[Theta]_,\[Phi]_,\[Tau]_}]:= Table[ Composition[ TranslationTransform[{x,y,z}+{0,0,platformHeight}], RotationTransform[\[Theta],{Sin[\[Theta]] Cos[\[Phi]],Cos[\[Theta]],Sin[\[Theta]] Sin[\[Phi]]}], RotationTransform[\[Phi],{Sin[\[Theta]] Cos[\[Phi]],Cos[\[Theta]],Sin[\[Theta]] Sin[\[Phi]]}], RotationTransform[\[Tau],{0,0,1}]][p], {p,relativePlatformPoints} ] ListPlot3D[PoseLegEndpoints[{0,0,0,0,0,0}]//N,PlotRange->{{-1,1},{-1,1},{-1,2}}] 
Posted 6 years ago
 Maybe I should leave this to the experts, but I've dug my hole now.As above, platformHeight=1; relativePlatformPoints := Table[{Cos[\[Theta]], Sin[\[Theta]], 0}, {\[Theta], Range[0, 5]/6 2 Pi}] But the RotationTransform seems to be much simpler: PoseLegEndpoints[{x_,y_,z_,\[Theta]_,\[Phi]_,\[Tau]_}]:= Table[ Composition[ TranslationTransform[{x,y,z}+{0,0,platformHeight}], RotationTransform[\[Theta],{1,0,0}], RotationTransform[\[Phi],{0,1,0}], RotationTransform[\[Tau],{0,0,1}] ] [p], {p,relativePlatformPoints} ] ListPlot3D[PoseLegEndpoints[{0,0,0,0,0,0}]//N,PlotRange->{{-1.5,1.5},{-1.5,1.5},{-1,2}}] Manipulate[ ListPlot3D[ PoseLegEndpoints[{x, y, z, \[Theta], \[Phi], \[Tau]}] // N, PlotRange -> {{-1.5, 1.5}, {-1.5, 1.5}, {-1, 2}}], {{x, 0}, -1, 1}, {{y, 0}, -1, 1}, {{z, 0}, -1, 1}, {{\[Theta], 0}, -1, 1}, {{\[Phi], 0}, -1, 1}, {{\[Tau], 0}, -1, 1}] 
Posted 6 years ago
 Thank you Eric. I'm a newbie, just downloaded Mathematica. My goal is to generate correct Motion data from this Stewart Platform Demo. Hence stupid questions. I pasted your Code to Demo file in the place of the original Code and the result is platform collapse. Any Ideas Your help is much appreciated Mario
Posted 6 years ago
 Hi Mario,Which demo are you referring to? If you are using System Modeler, I won't be of much help; I've never used it. If you are interested in the Stewart Platform itself, I can be of help. (But, be warned. I'm 68 years old and took up Mathematica as a retirement project. 35 years of programming microcontrollers in C is a lot procedural thinking to get over!)Back in 1999, I was tasked with the job of putting a Stewart mechanism in a pit in a new Posture and Gait lab. The professor insisted on buying the hydraulic actuators before the platform was designed. Using Working Model 3D, a new program that could model parallel mechanisms, I found that the Stewart Platform could hit the sides of the pit if it were to satisfy the range of motions required. So I had to invent a new mechanism.That required learning about parallel mechanisms, and the key to understanding them is degrees of freedom.The symmetrical design of the Stewart mechanism is not at all necessary. The actuators can be placed any-which-way as long as they aren't parallel at some point. And other degrees of freedom can be used, too. For another project, I invented a 2-degree of freedom motion base keeping x,y,z,and tau fixed.Eric
Posted 6 years ago
 Hi Eric, I'm referring to https://www.wolfram.com/system-modeler/industry-examples/industrial-manufacturing/stewart-platform-parallel-manipulator.html Yes it uses System Modeller, but Mathematica generates Motion Data and thats what I'm after. If you look at above example you'll see where the problem is. Inverse Kinematics generates motion data from Long Demonstration Plan. Any help is appreciated especially yours as you already worked with Stewart Mechanism. Thanks Mario
Posted 6 years ago
 Hi Mario,I downloaded SystemModeler onto my XP computer. Not compatible, it seems.I see now that the problem I was having with the code you supplied is that the Y axis is the vertical. The PoseLegEndpoints[] function seems to work OK, but the range of values that it works for is hard to determine using Manipulate (especially when everything is turned 90 degrees).Is the problem here: ExportMotionPlan[demoMotionPlan]; *Export::nodir: Directory C:\Documents and Settings\Eric Johnstone\Local Settings\Temp\wz4602\StewartPlatform\DocumentationFiles\ does not exist. >>* *OpenWrite::noopen: Cannot open C:\Documents and Settings\Eric Johnstone\Local Settings\Temp\wz4602\StewartPlatform\DocumentationFiles\PlatformPath.txt. >>* ?Or is that because I don't have SystemModeler? Is this the problem you are referring to?Eric
Posted 6 years ago
 Hi, yes it seems that Y is the vertical, which is weird and I can't figure it why. I'v run Evaluate Notebook in Mathematica only, without System Modeler running and it seems OKIt looks like PlatformPath.txt is saved in folder DocumentationFiles that has to be on the same root as Mathematica file StewartPlatform.nbAs I can see you'v saved Mathematica file in to Temp FolderC:\Documents and Settings\Eric Johnstone\Local Settings\Temp\wz4602\StewartPlatform\DocumentationFiles\PlatformPath.txt. >> ExportMotionPlan[poses_List, legoffsets_: {0, 0, 0, 0, 0, 0}] := Module[{framerate = 10, lengths, tabledata}, lengths = {First[poses]}; Do[lengths = Join[lengths, Rest@PoseRange[{Last[lengths], wp}, framerate]], {wp, Rest[poses]}]; AppendTo[lengths, Last[lengths]]; lengths = Map[PoseLegLengths, lengths]; lengths = Map[# + legoffsets &, lengths]; tabledata = MapIndexed[Prepend[#, (First[#2] - 1)/framerate] &, lengths]; {Export[ FileNameJoin[{NotebookDirectory[], "DocumentationFiles", "PlatformPath.txt"}], {{"LegLengths", tabledata}}, "ModelicaCombiTimeTable"], First[Last[tabledata]]} ] Mario
Posted 6 years ago
 Hi Mario,If you comment out the last line: ExportMotionPlan[poses_List,legoffsets_:{0,0,0,0,0,0}]:= Module[{framerate=10,lengths,tabledata}, lengths={First[poses]}; Do[lengths=Join[lengths,Rest@PoseRange[{Last[lengths],wp},framerate]],{wp,Rest[poses]}];AppendTo[lengths,Last[lengths]]; lengths=Map[PoseLegLengths,lengths]; lengths=Map[#+legoffsets&,lengths]; tabledata=MapIndexed[Prepend[#,(First[#2]-1)/framerate]&,lengths](*{Export[FileNameJoin[{NotebookDirectory[],"DocumentationFiles","PlatformPath.txt"}],{{"LegLengths",tabledata}},"ModelicaCombiTimeTable"],First[Last[tabledata]]}*) ] and run ExportMotionPlan[demoMotionPlan] without a semicolon, you get {{0,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{1/10,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{1/5,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{3/10,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{2/5,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{1/2,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{3/5,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{7/10,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{4/5,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{9/10,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{1,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{11/10,0.177146,0.172484,0.179639,0.171251,0.18149,0.168899},{6/5,0.184186,0.175092,0.189321,0.173459,0.193351,0.168897},{13/10,0.191352,0.178177,0.199365,0.177031,0.205731,0.170305},{7/5,0.198544,0.181744,0.209743,0.181978,0.218455,0.173031},{3/2,0.20568,0.185795,0.220421,0.188265,0.231373,0.176951},{8/5,0.212696,0.190332,0.231367,0.195819,0.244357,0.18191},{17/10,0.219538,0.195353,0.242545,0.204538,0.257296,0.187744},{9/5,0.226167,0.200858,0.25392,0.214302,0.270095,0.194285},{19/10,0.232553,0.206839,0.265457,0.224982,0.282669,0.201373},{2,0.238676,0.213291,0.277118,0.236445,0.294946,0.208859},{21/10,0.230679,0.210296,0.269809,0.229228,0.282619,0.196616},{11/5,0.221762,0.207329,0.263004,0.223376,0.270155,0.184527},{23/10,0.211962,0.204354,0.256696,0.218952,0.257687,0.172825},{12/5,0.201327,0.201351,0.250866,0.215975,0.245361,0.16177},{5/2,0.189923,0.198317,0.245485,0.21441,0.23333,0.151648},{13/5,0.177829,0.195261,0.240512,0.21418,0.221758,0.142763},{27/10,0.165141,0.192212,0.235902,0.215159,0.21082,0.135414},{14/5,0.151974,0.189211,0.231602,0.217194,0.200694,0.129866},{29/10,0.138468,0.186313,0.22756,0.220108,0.191559,0.126306},{3,0.124796,0.183587,0.223719,0.223719,0.183587,0.124796},{31/10,0.124796,0.183587,0.223719,0.223719,0.183587,0.124796},{16/5,0.124796,0.183587,0.223719,0.223719,0.183587,0.124796},{33/10,0.124796,0.183587,0.223719,0.223719,0.183587,0.124796},{17/5,0.124796,0.183587,0.223719,0.223719,0.183587,0.124796},{7/2,0.124796,0.183587,0.223719,0.223719,0.183587,0.124796},{18/5,0.124796,0.183587,0.223719,0.223719,0.183587,0.124796},{37/10,0.124796,0.183587,0.223719,0.223719,0.183587,0.124796},{19/5,0.124796,0.183587,0.223719,0.223719,0.183587,0.124796},{39/10,0.124796,0.183587,0.223719,0.223719,0.183587,0.124796},{4,0.124796,0.183587,0.223719,0.223719,0.183587,0.124796},{41/10,0.137276,0.184049,0.21631,0.21631,0.184049,0.137276},{21/5,0.150357,0.185189,0.209514,0.209514,0.185189,0.150357},{43/10,0.163992,0.187016,0.203326,0.203326,0.187016,0.163992},{22/5,0.178131,0.189531,0.197736,0.197736,0.189531,0.178131},{9/2,0.192728,0.192728,0.192728,0.192728,0.192728,0.192728},{23/5,0.207734,0.196591,0.188284,0.188284,0.196591,0.207734},{47/10,0.223101,0.201095,0.184381,0.184381,0.201095,0.223101},{24/5,0.238779,0.206211,0.180997,0.180997,0.206211,0.238779},{49/10,0.254719,0.211904,0.178112,0.178112,0.211904,0.254719},{5,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{51/10,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{26/5,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{53/10,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{27/5,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{11/2,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{28/5,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{57/10,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{29/5,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{59/10,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{6,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{61/10,0.270072,0.223851,0.17247,0.179826,0.212818,0.271964},{31/5,0.269577,0.229882,0.170187,0.184719,0.207987,0.273337},{63/10,0.269394,0.236145,0.168924,0.190282,0.203724,0.274971},{32/5,0.269524,0.242563,0.168717,0.196405,0.200112,0.276846},{13/2,0.269966,0.249062,0.169572,0.202979,0.197221,0.278939},{33/5,0.270714,0.255573,0.171463,0.2099,0.195114,0.281224},{67/10,0.271758,0.262033,0.17434,0.217068,0.193838,0.283674},{34/5,0.273084,0.268384,0.178126,0.224392,0.193422,0.28626},{69/10,0.274675,0.27457,0.182729,0.231787,0.193875,0.288953},{7,0.27651,0.280545,0.188044,0.239176,0.195188,0.291724},{71/10,0.274675,0.27457,0.182729,0.231787,0.193875,0.288953},{36/5,0.273084,0.268384,0.178126,0.224392,0.193422,0.28626},{73/10,0.271758,0.262033,0.17434,0.217068,0.193838,0.283674},{37/5,0.270714,0.255573,0.171463,0.2099,0.195114,0.281224},{15/2,0.269966,0.249062,0.169572,0.202979,0.197221,0.278939},{38/5,0.269524,0.242563,0.168717,0.196405,0.200112,0.276846},{77/10,0.269394,0.236145,0.168924,0.190282,0.203724,0.274971},{39/5,0.269577,0.229882,0.170187,0.184719,0.207987,0.273337},{79/10,0.270072,0.223851,0.17247,0.179826,0.212818,0.271964},{8,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{81/10,0.271505,0.217083,0.173486,0.178048,0.219296,0.270328},{41/5,0.27223,0.216141,0.171378,0.180494,0.220565,0.269877},{83/10,0.273044,0.215312,0.169392,0.183043,0.221939,0.269517},{42/5,0.273947,0.214595,0.167532,0.185692,0.223416,0.26925},{17/2,0.274938,0.213993,0.165801,0.188437,0.224995,0.269076},{43/5,0.276015,0.213507,0.164205,0.191273,0.226673,0.268994},{87/10,0.277179,0.213137,0.162746,0.194196,0.228448,0.269006},{44/5,0.278428,0.212883,0.16143,0.197203,0.230319,0.26911},{89/10,0.279761,0.212747,0.160258,0.200289,0.232281,0.269307},{9,0.281176,0.212728,0.159235,0.203452,0.234334,0.269597},{91/10,0.276592,0.213504,0.15774,0.202283,0.235039,0.264813},{46/5,0.272299,0.214744,0.156869,0.201605,0.236165,0.260325},{93/10,0.268309,0.216438,0.156632,0.201421,0.237707,0.256149},{47/5,0.264638,0.218578,0.157034,0.201734,0.239657,0.252301},{19/2,0.261298,0.221149,0.158068,0.20254,0.242005,0.248795},{48/5,0.258302,0.224138,0.159723,0.203834,0.244739,0.245647},{97/10,0.255662,0.227527,0.16198,0.205607,0.247846,0.24287},{49/5,0.25339,0.231299,0.164814,0.207847,0.251313,0.240477},{99/10,0.251495,0.235436,0.168195,0.210538,0.255126,0.238479},{10,0.249986,0.239918,0.172091,0.213664,0.259268,0.236887},{101/10,0.246891,0.240055,0.174124,0.207722,0.255644,0.236333},{51/5,0.244167,0.240609,0.1767,0.202101,0.252365,0.236201},{103/10,0.241826,0.241575,0.179796,0.196828,0.249444,0.236493},{52/5,0.239879,0.242949,0.183385,0.191931,0.246893,0.237206},{21/2,0.238337,0.244725,0.18744,0.18744,0.244725,0.238337},{53/5,0.237206,0.246893,0.191931,0.183385,0.242949,0.239879},{107/10,0.236493,0.249444,0.196828,0.179796,0.241575,0.241826},{54/5,0.236201,0.252365,0.202101,0.1767,0.240609,0.244167},{109/10,0.236333,0.255644,0.207722,0.174124,0.240055,0.246891},{11,0.236887,0.259268,0.213664,0.172091,0.239918,0.249986},{111/10,0.238479,0.255126,0.210538,0.168195,0.235436,0.251495},{56/5,0.240477,0.251313,0.207847,0.164814,0.231299,0.25339},{113/10,0.24287,0.247846,0.205607,0.16198,0.227527,0.255662},{57/5,0.245647,0.244739,0.203834,0.159723,0.224138,0.258302},{23/2,0.248795,0.242005,0.20254,0.158068,0.221149,0.261298},{58/5,0.252301,0.239657,0.201734,0.157034,0.218578,0.264638},{117/10,0.256149,0.237707,0.201421,0.156632,0.216438,0.268309},{59/5,0.260325,0.236165,0.201605,0.156869,0.214744,0.272299},{119/10,0.264813,0.235039,0.202283,0.15774,0.213504,0.276592},{12,0.269597,0.234334,0.203452,0.159235,0.212728,0.281176},{121/10,0.26911,0.230319,0.197203,0.16143,0.212883,0.278428},{61/5,0.268994,0.226673,0.191273,0.164205,0.213507,0.276015},{123/10,0.26925,0.223416,0.185692,0.167532,0.214595,0.273947},{62/5,0.269877,0.220565,0.180494,0.171378,0.216141,0.27223},{25/2,0.270871,0.218135,0.175711,0.175711,0.218135,0.270871},{63/5,0.27223,0.216141,0.171378,0.180494,0.220565,0.269877},{127/10,0.273947,0.214595,0.167532,0.185692,0.223416,0.26925},{64/5,0.276015,0.213507,0.164205,0.191273,0.226673,0.268994},{129/10,0.278428,0.212883,0.16143,0.197203,0.230319,0.26911},{13,0.281176,0.212728,0.159235,0.203452,0.234334,0.269597},{131/10,0.26751,0.212055,0.158143,0.205212,0.221794,0.259272},{66/5,0.253696,0.211706,0.157477,0.207555,0.210425,0.25043},{133/10,0.239942,0.211794,0.157219,0.210316,0.20034,0.24316},{67/5,0.226483,0.212425,0.157368,0.213346,0.191629,0.237498},{27/2,0.213586,0.213693,0.157939,0.216518,0.184349,0.233413},{68/5,0.201547,0.215677,0.15896,0.219725,0.178515,0.230809},{137/10,0.190685,0.218431,0.160466,0.222882,0.174095,0.229532},{69/5,0.181329,0.221986,0.162503,0.225923,0.171012,0.229378},{139/10,0.173794,0.226345,0.165115,0.228801,0.169146,0.230112},{14,0.168346,0.231483,0.168346,0.231483,0.168346,0.231483},{141/10,0.164621,0.224944,0.164621,0.224944,0.164621,0.224944},{71/5,0.161675,0.21831,0.161675,0.21831,0.161675,0.21831},{143/10,0.159579,0.211641,0.159579,0.211641,0.159579,0.211641},{72/5,0.15839,0.205004,0.15839,0.205004,0.15839,0.205004},{29/2,0.15814,0.198472,0.15814,0.198472,0.15814,0.198472},{73/5,0.158836,0.192123,0.158836,0.192123,0.158836,0.192123},{147/10,0.160458,0.186044,0.160458,0.186044,0.160458,0.186044},{74/5,0.162963,0.180325,0.162963,0.180325,0.162963,0.180325},{149/10,0.166287,0.175062,0.166287,0.175062,0.166287,0.175062},{15,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{151/10,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{76/5,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{153/10,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{77/5,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{31/2,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{78/5,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{157/10,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{79/5,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{159/10,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{16,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035},{161/10,0.17035,0.17035,0.17035,0.17035,0.17035,0.17035}}Is this the text you are looking for?Eric
Posted 6 years ago
 yes Leg Lengths are what I'm looking for, but they are not calculated correctly. If you change Long Demonstration Motion Plan, just one Angle at a time to something like this demoMotionPlan = Block[{dx = 0.05, d\[Theta] = 0.5}, { {0, 0, 0, 0, 0, 0}, {0, 0, 0, d\[Theta], 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, -d\[Theta], 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, d\[Theta], 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, -d\[Theta], 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, d\[Theta]}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, -d\[Theta]}, {0, 0, 0, 0, 0, 0} } ]; Leg lengths are not calculated for [Phi]. Any Ideas Mario
Posted 6 years ago
 Hi Mario,It took a while to go through the code, but I finally get the problem. I don't know what it is; you may have found a bug in Mathematica. But if you use separate RotationTrransforms like this: PoseLegEndpoints[{x_, y_, z_, \[Theta]_, \[Phi]_, \[Tau]_}] := Table[Composition[ TranslationTransform[{x, y, z} + {0, platformHeight, 0}], RotationTransform[\[Theta], {1, 0, 0}], RotationTransform[\[Phi], {0, 0, 1}], RotationTransform[\[Tau], {0, 1, 0}]][p], {p, relativePlatformPoints}] the second angle calculates.For a motion path of testMotionPlan = Block[{dx = 0.05, d\[Theta] = 0.5}, { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, d\[Theta], 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, -d\[Theta], 0}, {0, 0, 0, 0, 0, 0} } ]; the platform returns to its rest position at the {0, 0, 0, 0, 0, 0} points.I used the ExportMotionPlan[] function with the last line commented out, as above.Use MatrixPlot[] to see how the leg lengths change.Eric
Posted 6 years ago
 Hi Mario,I've been playing around with the RotationTransform. Using it in the form that the author does, where he is transforming the vertical vector, {0, 1, 0}, by another vector {Sin[\[Theta]] Cos[\[Phi]], Cos[\[Theta]], Sin[\[Theta]] Sin[\[Phi]]} cannot be generated by successive theta and phi transformations.So, although my workaround seems to work, it doesn't give the behaviour that the author intended. RotationTransform[{{0,1,0},{Sin[\[Theta]]Cos[\[Phi]],Cos[\[Theta]],Sin[\[Theta]]Sin[\[Phi]]}}] seems to work. Hey, but, in looking at it, if theta is 0, {Sin[\[Theta]]Cos[\[Phi]],Cos[\[Theta]],Sin[\[Theta]]Sin[\[Phi]]} evaluates to {0,Cos[theta],0}, so the phi value doesn't get through.Could this be the problem?Eric
Posted 6 years ago
 Hi Eric, I tested your workaround and it works. It is also unusual that z vertical is in second position,so instead x,y,z it is x,z,y. You are right phi get's calculated only if theta is not 0.Mario
Posted 6 years ago
 Hi Mario,Mathematica seems to flip the meanings of theta and phi. According to the documentation for SphericalPlot3D:(Pi/2 - theta) corresponds to "latitude"; theta is 0 at the "north pole", and Pi at the "south pole". Phi corresponds to "longitude", varying from 0 to 2 Pi counterclockwise looking from the north pole.My text books reverse the definitions of theta and phi.So, with this in mind, there is nothing wrong with the PoseLegEndpoints[] function. If theta is zero, the vector is pointing towards the north pole, so the value of phi is immaterial. Eric
Posted 6 years ago
 yes this is true for SphericalPlot3D. But original Inverse Kinematics Calculations are wrong. If you enter 5cm change in x,y z or correctly x,z,y direction you get the following results : {PoseLegLengths[{0, 0, 0, 0, 0, 0}], PoseLegLengths[{0.05, 0, 0, 0, 0, 0}]} {{0.17035, 0.17035, 0.17035, 0.17035, 0.17035, 0.17035}, {0.155246, 0.19491, 0.180185, 0.180185, 0.19491, 0.155246}} {PoseLegLengths[{0, 0, 0, 0, 0, 0}], PoseLegLengths[{0, 0.05, 0, 0, 0, 0}]} {{0.17035, 0.17035, 0.17035, 0.17035, 0.17035, 0.17035}, {0.215683, 0.215683, 0.215683, 0.215683, 0.215683, 0.215683}} {PoseLegLengths[{0, 0, 0, 0, 0, 0}], PoseLegLengths[{0, 0, 0.05, 0, 0, 0}]} {0.17035, 0.17035, 0.17035, 0.17035, 0.17035, 0.17035}, {0.186301, 0.16337, 0.1533, 0.198841, 0.190654, 0.168317}} and changing [Theta], [Phi], [Tau]_} angels 10 degree {PoseLegLengths[{0, 0, 0, 0, 0, 0}], PoseLegLengths[{0, 0, 0, 10 \[Degree], 0, 0}]} {{0.17035, 0.17035, 0.17035, 0.17035, 0.17035, 0.17035}, {0.160146, 0.166254, 0.185371, 0.185371, 0.166254, 0.160146}} {PoseLegLengths[{0, 0, 0, 0, 0, 0}], PoseLegLengths[{0, 0, 0, 0, 10 \[Degree], 0}]} {{0.17035, 0.17035, 0.17035, 0.17035, 0.17035, 0.17035}, {0.17035, 0.17035, 0.17035, 0.17035, 0.17035, 0.17035}} CALCULATION ERROR {PoseLegLengths[{0, 0, 0, 0, 0, 0}], PoseLegLengths[{0, 0, 0, 0, 0, 10 \[Degree]}]} As one can immediately notice, only [Phi] calculation gives the result for Zero Degree.Any Ideas Mario
Posted 6 years ago
 This is the way spherical coordinates are usually presented, but Mathematica interchanges theta and phi. When theta is zero in PoseLegEndpoints[], (phi in the diagram), the vector is pointing straight up, right at the north pole. This vector is the normal to the platform surface; that is, the platform surface has to move so that its surface is normal to the vector OP in the diagram.This is what the line of code RotationTransform[{{0,1,0},{Sin[\[Theta]]Cos[\[Phi]],Cos[\[Theta]],Sin[\[Theta]]Sin[\[Phi]]}}] does. It takes the vector {0,1,0} (the vertical) and transforms it to {Sin[\[Theta]]Cos[\[Phi]],Cos[\[Theta]],Sin[\[Theta]]Sin[\[Phi]]}.The {0,1,0} vector is the z axis in the diagram and the OP vector is {Sin[\[Theta]]Cos[\[Phi]],Cos[\[Theta]],Sin[\[Theta]]Sin[\[Phi]]}.But the author has thrown a double whammy by making the y axis the vertical and interchanging theta and phi.Now look at the z axis in the diagram. If the OP vector is on the z axis, any value of theta (in the diagram) will not change the vertical position of the vector OP.So the PoseLegEndpoints[] is correct in not changing the leg lengths if theta is zero and phi is any other value.Does that make sense?Eric
Posted 6 years ago
 Hi Eric, I watched Wolfram Video ScreenCast at http://www.wolfram.com/broadcast/video.php?c=202&v=835and I'm still confused about double flip y,z and Phi.I also want to change the number of poses per second, originally 10 to 50.I'v changed frame rate from 10 to 50, but I get the same amount of lines in file PlatformPath.txt. ExportMotionPlan[poses_List, legoffsets_: {0, 0, 0, 0, 0, 0}] := Module[{framerate = 50, lengths, tabledata}, lengths = {First[poses]}; Do[lengths = Join[lengths, Rest@PoseRange[{Last[lengths], wp}, framerate]], {wp, Rest[poses]}]; AppendTo[lengths, Last[lengths]]; lengths = Map[PoseLegLengths, lengths]; lengths = Map[# + legoffsets &, lengths]; tabledata = MapIndexed[Prepend[#, (First[#2] - 1)/framerate] &, lengths]; {Export[ FileNameJoin[{NotebookDirectory[], "DocumentationFiles", "PlatformPath.txt"}], {{"LegLengths", tabledata}}, "ModelicaCombiTimeTable"], First[Last[tabledata]]} Mario
Posted 6 years ago
 Hi Mario,Coming to terms with the z,y and theta,phi interchanges requires some contemplation. It's like driving in England compared to the USA. You have to change the side of the road you call legal.I tried the ExportMotionPlan[] with framerate=50 and it works OK. Don't forget that you have to re-compile it by hitting shift-enter after changing the framerate.Eric
Posted 6 years ago
 Hi Eric, yes you are right, one has to follow certain rules like shift_enter.You are a great help. I have many questions but I don't want to bother youtoo much ...with all of them.ThanksMario
Posted 6 years ago
Posted 6 years ago
 Hi Eric, yeah me too. I would like to modify the code so that I can enter pose data in Long demonstration motion plan but every second as it is now, but instead only at certain time positions: like the following example:pose 1 at 1sec,pose 2 at 4sec,pose 3 at 4,5sec,etc. Any suggestions ? Mario
Posted 6 years ago
 Hi Mario,In this utility function for generating a sequence of steps between two poses: PoseRange[{pose1_, pose2_}, steps_] := Table[pose1 + t (pose2 - pose1), {t, Range[0, 1, 1/steps]}] there is a hidden time value. It is the 1 in Range[0, 1, 1/steps]This generates a list of numbers between 0 and 1 divided into the number of frames per second.So, for 10 frames per second, it generates In[89]:= Range[0,1,1/10] Out[89]= {0,1/10,1/5,3/10,2/5,1/2,3/5,7/10,4/5,9/10,1} Now, you want to generate poses at arbitrary times, which must be chopped into steps. Suppose you want to go from 2.21 to 3.33 seconds at 10 frames per second. This would generate the series: In[87]:= Range[2.21,3.33,1/10] Out[87]= {2.21,2.31,2.41,2.51,2.61,2.71,2.81,2.91,3.01,3.11,3.21,3.31} This doesn't get right up to the 3.33 seconds time, because that falls in between the time frame periods. Depending on how important this is to you, it might have to be dealt with or disregarded. Let's disregard it for now and only use time divisions that are perfect multiples of the framerate periods. (By the way, if you don't mind, why are you looking at the Stewart Platform?)Now that you are adding time to the motion plan, we will need a time element in the motion plan: { {0, 0, 0.000, 0, 0, 0, 0}, {1, 0, 0.010, 0, 0, 0, 0}, {4, 0, 0.040, 0, 0, 0, 0}, {4.5, 0, 0.045, 0, 0, 0, 0} } where the first number is the time.So the PoseRange[] function now has to include the start and end times for the poses: PoseRange[{pose1_, pose2_}, steps_, time1_, time2_] := Table[pose1 + t/(time2 - time1) (pose2 - pose1), {t, Range[0, time2 - time1, 1/steps]}] This will generate however many poses are required between time1 and time2 every 1/framerate seconds. And now, to generate the poses, the ExportMotionPlan[] has to be modified to accommodate the new motion plan's extra time element: ExportMotionPlan[poses_List, legoffsets_: {0, 0, 0, 0, 0, 0}] := Module[{framerate = 10, lengths, tabledata, time1, time2}, lengths = {poses[[1, 2 ;; 7]]}; time1 := poses[[1, 1]]; Do[ ( time2 := wp[[1]]; lengths = Join[lengths, Rest@PoseRange[{Last[lengths], wp[[2 ;; 7]]}, framerate, time1, time2]]; time1 = time2; ), {wp, Rest[poses]}]; AppendTo[lengths, Last[lengths]]; lengths = Map[PoseLegLengths, lengths]; lengths = Map[# + legoffsets &, lengths]; tabledata = MapIndexed[Prepend[#, (First[#2] - 1)/framerate] &, lengths](*; {Export[ FileNameJoin[{NotebookDirectory[], "DocumentationFiles", "PlatformPath.txt"}], {{"LegLengths", tabledata}}, "ModelicaCombiTimeTable"], First[Last[tabledata]]}*) ] Note that the last line is commented out so that you see results directly in the notebook.So, with a motionPlan such as: motionPlan = { {0, 0, 0.00, 0, 0, 0, 0}, {1, 0, 0.01, 0, 0, 0, 0}, {3, 0, -0.03, 0, 0, 0, 0}, {4, 0, 0.04, 0, 0, 0, 0}, {4.5, 0, -0.045, 0, 0, 0, 0} }; ExportMotionPlan[motionPlan] // MatrixForm ( 0 0.17035 0.17035 0.17035 0.17035 0.17035 0.17035 1/10 0.171232 0.171232 0.171232 0.171232 0.171232 0.171232 1/5 0.172114 0.172114 0.172114 0.172114 0.172114 0.172114 3/10 0.172998 0.172998 0.172998 0.172998 0.172998 0.172998 2/5 0.173883 0.173883 0.173883 0.173883 0.173883 0.173883 1/2 0.174769 0.174769 0.174769 0.174769 0.174769 0.174769 3/5 0.175657 0.175657 0.175657 0.175657 0.175657 0.175657 7/10 0.176545 0.176545 0.176545 0.176545 0.176545 0.176545 4/5 0.177435 0.177435 0.177435 0.177435 0.177435 0.177435 9/10 0.178326 0.178326 0.178326 0.178326 0.178326 0.178326 1 0.179218 0.179218 0.179218 0.179218 0.179218 0.179218 11/10 0.177435 0.177435 0.177435 0.177435 0.177435 0.177435 6/5 0.175657 0.175657 0.175657 0.175657 0.175657 0.175657 13/10 0.173883 0.173883 0.173883 0.173883 0.173883 0.173883 7/5 0.172114 0.172114 0.172114 0.172114 0.172114 0.172114 3/2 0.17035 0.17035 0.17035 0.17035 0.17035 0.17035 8/5 0.168592 0.168592 0.168592 0.168592 0.168592 0.168592 17/10 0.166839 0.166839 0.166839 0.166839 0.166839 0.166839 9/5 0.165092 0.165092 0.165092 0.165092 0.165092 0.165092 19/10 0.16335 0.16335 0.16335 0.16335 0.16335 0.16335 2 0.161614 0.161614 0.161614 0.161614 0.161614 0.161614 21/10 0.159885 0.159885 0.159885 0.159885 0.159885 0.159885 11/5 0.158162 0.158162 0.158162 0.158162 0.158162 0.158162 23/10 0.156446 0.156446 0.156446 0.156446 0.156446 0.156446 12/5 0.154736 0.154736 0.154736 0.154736 0.154736 0.154736 5/2 0.153033 0.153033 0.153033 0.153033 0.153033 0.153033 13/5 0.151338 0.151338 0.151338 0.151338 0.151338 0.151338 27/10 0.14965 0.14965 0.14965 0.14965 0.14965 0.14965 14/5 0.14797 0.14797 0.14797 0.14797 0.14797 0.14797 29/10 0.146298 0.146298 0.146298 0.146298 0.146298 0.146298 3 0.144635 0.144635 0.144635 0.144635 0.144635 0.144635 31/10 0.150493 0.150493 0.150493 0.150493 0.150493 0.150493 16/5 0.156446 0.156446 0.156446 0.156446 0.156446 0.156446 33/10 0.162482 0.162482 0.162482 0.162482 0.162482 0.162482 17/5 0.168592 0.168592 0.168592 0.168592 0.168592 0.168592 7/2 0.174769 0.174769 0.174769 0.174769 0.174769 0.174769 18/5 0.181006 0.181006 0.181006 0.181006 0.181006 0.181006 37/10 0.187297 0.187297 0.187297 0.187297 0.187297 0.187297 19/5 0.193637 0.193637 0.193637 0.193637 0.193637 0.193637 39/10 0.200021 0.200021 0.200021 0.200021 0.200021 0.200021 4 0.206444 0.206444 0.206444 0.206444 0.206444 0.206444 41/10 0.190914 0.190914 0.190914 0.190914 0.190914 0.190914 21/5 0.175657 0.175657 0.175657 0.175657 0.175657 0.175657 43/10 0.160749 0.160749 0.160749 0.160749 0.160749 0.160749 22/5 0.146298 0.146298 0.146298 0.146298 0.146298 0.146298 9/2 0.132455 0.132455 0.132455 0.132455 0.132455 0.132455 23/5 0.132455 0.132455 0.132455 0.132455 0.132455 0.132455 ) It took a while to figure this out. Examine the code , see what you can understand, and ask about what you don't.Eric
Posted 6 years ago
 Hi Eric , thank you again. I replaced original code with yours, what is confusing me is whether motionPlan = { {0, 0, 0.00, 0, 0, 0, 0}, {1, 0, 0.01, 0, 0, 0, 0}, {3, 0, -0.03, 0, 0, 0, 0}, {4, 0, 0.04, 0, 0, 0, 0}, {4.5, 0, -0.045, 0, 0, 0, 0} }; is Short test motion plan or Long demonstration motion plan?RegardsMario
Posted 6 years ago
 Hi mario,It's its own plan. The long and short plans are just longer or shorter. Their structure is the same. But the motionPlan I implemented doesn't use the Block[]. That was necessary for the substitutions of dx and dtheta. Inside the Blocks[] you will see the basic structure; a List[] of List[]s.Eric
Posted 6 years ago
 Hi Eric,of course you are right.I added the following to the end of NoteBook to generate another file PlatformPath 2.txt wit leg offsets ExportMotionPlan[poses_List, legoffsets_: {-1.13137, -1.13137, -1.13137, -1.13137, -1.13137, -1.13137}] := Module[{framerate = 50, lengths, tabledata, time1, time2}, lengths = {poses[[1, 2 ;; 7]]}; time1 := poses[[1, 1]]; Do[(time2 := wp[[1]]; lengths = Join[lengths, Rest@PoseRange[{Last[lengths], wp[[2 ;; 7]]}, framerate, time1, time2]]; time1 = time2;), {wp, Rest[poses]}]; AppendTo[lengths, Last[lengths]]; lengths = Map[PoseLegLengths, lengths]; lengths = Map[# + legoffsets &, lengths]; tabledata = MapIndexed[Prepend[#, (First[#2] - 1)/framerate] &, lengths]; {Export[ FileNameJoin[{NotebookDirectory[], "DocumentationFiles", "PlatformPath 2.txt"}], {{"LegLengths", tabledata}}, "ModelicaCombiTimeTable"], First[Last[tabledata]]} ] motionPlan = { {0, 0, 0, 0, 0, 0, 0}, {1, 0, 0.01, 0, 0, 0, 0}, {3, 0, -0.03, 0, 0, 0, 0}, {4, 0, 0.04, 0, 0, 0, 0}, {4.5, 0, -0.045, 0, 0, 0, 0}, {8.5, 0, 0.3, 0, 0, 0, 0}, {10.5, 0, 0.3, 0, 0, 10 \[Degree], 0}, {16, 0, 0, 0, 0, 0, 0} }; ExportMotionPlan[motionPlan]; Unfortunately the result is not what I expected. What am I doing wrong this time? Mario
Posted 6 years ago
 Hi Mario,The purpose legoffsets is not documented. I'm not sure that adding a fixed length to the legs would produce the same motion in the extended actuators that the original actuators produced. For example, suppose each leg is extended 0.17035 units. The height of the platform is 0.15 units and the rest length of the legs (i.e., at neutral position) is 0.17035 units. This would presumably raise the working height of the platform to about twice its original height. But as the lengths of the actuators change, the positions of the extensions (assuming the extensions go from the platform's base to bottoms of the actuators) will change, so the previously fixed base points of the actuators will now be moving.If actuator extensions are required they should be incorporated before the calculations are made.For instance, suppose the platformHeight is changed to 0.3 from its original 0,15, the rest lengths are 0.17035 and 0.310675. The difference is 0.140325. If this is added to the 0.17035 lengths by using the legoffsets, the resulting motion is different.Could someone offer and idea of what the purpose legoffsets might be?Eric
Posted 6 years ago
 Hi Eric, I'm also confused about leg offsets purpose.What I would like to do is to read PlatformPath.txt that was generated by ExportMotionPlan....and substract initial leg length or any other arbitrary number from all of leg lengths written in file PlatformPath.txt and save it as PlatformPath 2.txt Mario
Posted 6 years ago
 Hi Mario,I haven't been able to install SystemModeler on my old XP computer, so I don't have the elements needed to do the export. You'll have to stick to the notebook output for this discussion.Can you re-phase your problem? Note that subtracting leg lengths will not give the motion that was originally calculated. Why do you want to do this? Or are you just verifying that the path will be different?Generating a path from the leg lengths is called the forward kinematics. It was this problem that was difficult to solve in 1999 when I discovered that the path of the intended Stewart platform could hit the walls of the pit it was to be housed in.Maybe you could import the path file back into Mathematica and we could work on it.Eric
Posted 6 years ago
 Hi Eric, yes that's what I had in mind to import path file back at the end of this Notebook or even a new one.Mario
Posted 6 years ago
 Hi Mario,Here is what the legoffsets are about:Suppose you are using hydraulic actuators for the legs. The control signal tells the actuator to extend so many meters from the retracted position. The retracted position is the "legoffset". The distance that you want the actuator to extend is the calculated length minus the retracted length. So, the legoffset could have been called "retracted length" and the code could have subtracted the legoffset instead of adding it. That would have been a little clearer.On the other hand, the neutral position might be the reference length, depending on the way the software is arranged, so this could be the offset.Eric
Posted 6 years ago
 Hi Eric, yes that is correct. I would like to Export two Motion Plans, oneas it is and the other one with Leg Offsets, but I was not successfulby copying ExportMotionPlan Cell and Entering Values in Offset Field.Any suggestions?Regards Mario
Posted 6 years ago
 Hi Mario,You can try this: ExportMotionPlan[poses_List, legoffsets_: {0, 0, 0, 0, 0, 0}] := Module[{framerate = 10, lengths, tabledata, time1, time2}, lengths = {poses[[1, 2 ;; 7]]}; time1 := poses[[1, 1]]; Do[ ( time2 := wp[[1]]; lengths = Join[lengths, Rest@PoseRange[{Last[lengths], wp[[2 ;; 7]]}, framerate, time1, time2]]; time1 = time2; ), {wp, Rest[poses]}]; AppendTo[lengths, Last[lengths]]; lengths = Map[PoseLegLengths, lengths]; tabledata = MapIndexed[Prepend[#, (First[#2] - 1)/framerate] &, lengths]; {Export[ FileNameJoin[{NotebookDirectory[], "DocumentationFiles", "PlatformPath1.txt"}], {{"LegLengths", tabledata}}, "ModelicaCombiTimeTable"], First[Last[tabledata]]}; lengths = Map[# + legoffsets &, lengths]; tabledata = MapIndexed[Prepend[#, (First[#2] - 1)/framerate] &, lengths]; {Export[ FileNameJoin[{NotebookDirectory[], "DocumentationFiles", "PlatformPath2.txt"}], {{"LegLengths", tabledata}}, "ModelicaCombiTimeTable"], First[Last[tabledata]]} ] I haven't tested this code, of course, because I don't have SystemModeler.A good value to test the offsets would be -0.17035, the zero-position leg length.Eric
Posted 6 years ago
 Hi Eric, I copied your Code at the end of the Notebook. Replaced Zeroes with Offset Value and I'v received the following error: Syntax::sntxf: "legoffsets_:" cannot be followed by "{1.1313669977935081,1.1313669977935081,1.1313669977935081,1.1313669977935081,1.1313669977935081,1.1313669977935081}". Mario
 Hi Mario,Did you use something like:ExportMotionPlan[motionPlan,legoffsets_: -{0.17035,0.17035,0.17035,0.17035,0.17035,0.17035}]?The legoffsets_:{...} idiom is only used in the definition of the function. When you call the function, use: ExportMotionPlan[ motionPlan, -{0.17035,0.17035,0.17035,0.17035,0.17035,0.17035} ] Note that using an offset of 1.1313669977935081 is not realistic because the platform height is only 0.15 units. You will get leg lengths, but they won't be very meaningful. The purpose of subtracting the offsets is to get control values for the servo actuators.Eric
 Hi Eric, I'v found the solution to the problem: So your Code: ExportMotionPlan[poses_List, legoffsets_: {0, 0, 0, 0, 0, 0}] := Module[{framerate = 10, lengths, tabledata, time1, time2}, lengths = {poses[[1, 2 ;; 7]]}; time1 := poses[[1, 1]]; Do[ ( time2 := wp[[1]]; lengths = Join[lengths, Rest@PoseRange[{Last[lengths], wp[[2 ;; 7]]}, framerate, time1, time2]]; time1 = time2; ), {wp, Rest[poses]}]; AppendTo[lengths, Last[lengths]]; lengths = Map[PoseLegLengths, lengths]; tabledata = MapIndexed[Prepend[#, (First[#2] - 1)/framerate] &, lengths]; {Export[ FileNameJoin[{NotebookDirectory[], "DocumentationFiles", "PlatformPath1.txt"}], {{"LegLengths", tabledata}}, "ModelicaCombiTimeTable"], First[Last[tabledata]]}; lengths = Map[# + legoffsets &, lengths]; tabledata = MapIndexed[Prepend[#, (First[#2] - 1)/framerate] &, lengths]; {Export[ FileNameJoin[{NotebookDirectory[], "DocumentationFiles", "PlatformPath2.txt"}], {{"LegLengths", tabledata}}, "ModelicaCombiTimeTable"], First[Last[tabledata]]} ] is correct and the error I was getting: Syntax::sntxf: "legoffsets_:" cannot be followed by "{1.1313669977935081,1.1313669977935081,1.1313669977935081,1.1313669977935081,1.1313669977935081,1.131366997793508 can be avoided just by deleting the colon in egoffsets_: and retyping it again.I don't know why, but it works.I wonder if you have any suggestion for my next question:In Motion plan one can enter platform positions at certain time, then the positions (frames) are calculated in linear way. I wold like to change that by using for instance logaritmic or any other curve.Any Ideas how.RegardsMario