TCPIPexudynMatlab.py

You can view and download this file on Github: TCPIPexudynMatlab.py

  1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2# This is an EXUDYN example
  3#
  4# Details:  Example for connecting MATLAB with Exudyn/Python via TCP/IP
  5#           See file TCPIPmatlab.slx for the according Simulink model
  6#
  7# Author:   Johannes Gerstmayr
  8# Date:     2021-11-06
  9#
 10# Copyright:This file is part of Exudyn. Exudyn is free software. You can redistribute it and/or modify it under the terms of the Exudyn license. See 'LICENSE.txt' for more details.
 11#
 12#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 13
 14import exudyn as exu
 15from exudyn.itemInterface import *
 16from exudyn.utilities import *
 17from exudyn.graphicsDataUtilities import *
 18
 19import numpy as np
 20
 21
 22#the following way works between Python and MATLAB-Simulink (client),
 23#and gives stable results(with only delay of one step):
 24#
 25# TCP/IP Client Send:
 26#   priority = 2 (in properties)
 27#   blocking = false
 28#   Transfer Delay on (but off also works)
 29# TCP/IP Client Receive:
 30#   priority = 1 (in properties)
 31#   blocking = true
 32#   Sourec Data type = double
 33#   data size = number of double in packer
 34#   Byte order = BigEndian
 35#   timeout = 10
 36
 37
 38
 39
 40#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 41#set up double pendulum:
 42
 43SC = exu.SystemContainer()
 44mbs = SC.AddSystem()
 45
 46#create an environment for mini example
 47
 48
 49L = 1
 50fL = 2.5
 51background = GraphicsDataQuad([[-fL*L, -fL*L, 0],[fL*L, -fL*L, 0],[fL*L, 1*L, 0],[-fL*L, 1*L, 0]],
 52                              color4darkgrey, nTiles=8,
 53                              alternatingColor=color4lightgrey)
 54oGround=mbs.AddObject(ObjectGround(referencePosition= [0,0,0],
 55                                   visualization=VObjectGround(graphicsData= [background])))
 56a = L     #x-dim of pendulum
 57b = 0.05    #y-dim of pendulum
 58massRigid = 12
 59inertiaRigid = massRigid/12*(2*a)**2
 60g = 9.81    # gravity
 61
 62graphicsCube = GraphicsDataOrthoCubePoint(centerPoint=[0,0,0], size=[L,b,b], color=color4steelblue)
 63nRigid0 = mbs.AddNode(Rigid2D(referenceCoordinates=[0.5*L,0,0], initialVelocities=[0,0,0]));
 64oRigid0 = mbs.AddObject(RigidBody2D(physicsMass=massRigid, physicsInertia=inertiaRigid,nodeNumber=nRigid0,
 65                                   visualization=VObjectRigidBody2D(graphicsData= [graphicsCube])))
 66
 67mR0 = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oRigid0, localPosition=[-0.5*L,0.,0.])) #support point
 68mR0com = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oRigid0, localPosition=[ 0.,0.,0.])) #mid point
 69mR0end = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oRigid0, localPosition=[ 0.5*L,0.,0.])) #end point
 70
 71mG0 = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oGround, localPosition=[0.,0.,0.]))
 72mbs.AddObject(RevoluteJoint2D(markerNumbers=[mG0,mR0]))
 73
 74mbs.AddLoad(Force(markerNumber = mR0com, loadVector = [0, -massRigid*g, 0]))
 75
 76nRigid1 = mbs.AddNode(Rigid2D(referenceCoordinates=[1.5*L,0,0], initialVelocities=[0,0,0]));
 77oRigid1 = mbs.AddObject(RigidBody2D(physicsMass=massRigid, physicsInertia=inertiaRigid,nodeNumber=nRigid1,
 78                                   visualization=VObjectRigidBody2D(graphicsData= [graphicsCube])))
 79
 80mR1 = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oRigid1, localPosition=[-0.5*L,0.,0.])) #support point
 81mR1com = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oRigid1, localPosition=[ 0.,0.,0.])) #mid point
 82
 83mbs.AddObject(RevoluteJoint2D(markerNumbers=[mR0end,mR1]))
 84
 85mbs.AddLoad(Force(markerNumber = mR1com, loadVector = [0, -massRigid*g, 0]))
 86
 87#++++++++++++++++++++++++++++++++++++++++++++++++++
 88#damper:
 89mR0C2 = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nRigid0, coordinate=2)) #phi
 90mR1C2 = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nRigid1, coordinate=2)) #phi
 91mbs.AddObject(CoordinateSpringDamper(markerNumbers=[mR0C2,mR1C2],
 92                                     stiffness=0, damping=10,
 93                                     visualization=VCoordinateSpringDamper(show=False)))
 94
 95#%%++++++++++++++++++++++++++++++++++++++++++++++++++
 96#connect to MATLAB:
 97loadTorque = mbs.AddLoad(Torque(markerNumber = mR0com, loadVector = [0, 0, 0]))
 98sensorAngle = mbs.AddSensor(SensorBody(bodyNumber=oRigid0, outputVariableType=exu.OutputVariableType.Rotation,
 99                                       fileName='solution/test.txt',
100                                       writeToFile=False))
101sensorAngle_t = mbs.AddSensor(SensorBody(bodyNumber=oRigid0, outputVariableType=exu.OutputVariableType.AngularVelocity,
102                                       fileName='solution/test_t.txt',
103                                       writeToFile=False))
104
105
106
107mbs.sys['TCPIPobject'] = CreateTCPIPconnection(sendSize=3, receiveSize=2,
108                                               bigEndian=True, verbose=True)
109sampleTime = 0.01 #sample time in MATLAB! must be same!
110mbs.variables['tLast'] = 0
111
112def PreStepUserFunction(mbs, t):
113    if t >= mbs.variables['tLast'] + sampleTime:
114        mbs.variables['tLast'] += sampleTime
115
116        tcp = mbs.sys['TCPIPobject']
117        phi0 = mbs.GetSensorValues(sensorAngle)
118        #print(phi0)
119        phi0_t = mbs.GetSensorValues(sensorAngle_t)[2]
120
121        y = TCPIPsendReceive(tcp, np.array([t, phi0, phi0_t])) #time, torque
122        tau = y[1]
123        mbs.SetLoadParameter(loadTorque, 'loadVector',[0,0,tau])
124    return True
125
126
127try:
128    mbs.SetPreStepUserFunction(PreStepUserFunction)
129
130    #%%++++++++++++++++++++++++++++++++++++++++++++++++++
131    mbs.Assemble()
132    print(mbs)
133
134    simulationSettings = exu.SimulationSettings() #takes currently set values or default values
135
136    h = 0.002
137    tEnd = 10
138    simulationSettings.timeIntegration.numberOfSteps = int(tEnd/h)
139    simulationSettings.timeIntegration.endTime = tEnd
140    simulationSettings.timeIntegration.newton.relativeTolerance = 1e-8*100 #10000
141    simulationSettings.timeIntegration.newton.absoluteTolerance = 1e-10
142    simulationSettings.timeIntegration.verboseMode = 1
143    # simulationSettings.timeIntegration.simulateInRealtime = True
144
145    simulationSettings.timeIntegration.newton.useModifiedNewton = False
146    simulationSettings.timeIntegration.newton.numericalDifferentiation.minimumCoordinateSize = 1
147    simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 0.5
148    simulationSettings.displayStatistics = True
149
150    #SC.visualizationSettings.nodes.defaultSize = 0.05
151
152    simulationSettings.solutionSettings.solutionInformation = "Rigid pendulum"
153
154    exu.StartRenderer()
155
156
157    mbs.SolveDynamic(simulationSettings)
158
159    SC.WaitForRenderEngineStopFlag()
160    exu.StopRenderer() #safely close rendering window!
161
162finally:
163    CloseTCPIPconnection(mbs.sys['TCPIPobject'])