From: Kailas N. <ka...@my...> - 2008-02-05 21:52:59
Attachments:
ApolloBody.py
|
Hi! I'm working on a program in visual python and am running into a weird problem (maybe it's my own user error, but I can't see what I'm doing wrong) To run the attached code, need wxpython installed too. In my code, I've got a "human body" constructed using some primitive blocks, cylinders, etc. I want to be able to model upper torso movement, as well as arm movement that's recorded by some sensors placed around the body. The arm movement works great, and I can easily control the position and rotation of the upper arm and elbow (all that I'm interested in). The torso is behaving a bit strangely. I have a Box object I create: Chest = box ( pos=(0,HeadDiameter+SegmentSpace+HeadDiameter/2,0), axis=(2*HeadDiameter,0,0), width=.75, height=HeadDiameter, length=2*HeadDiameter, color=color.red) And based on the "pitch", "yaw" and "heading" angles, I can rotate it. When the chest pitches forward, it needs to rotate about the line that goes through the gap between the torso and stomach, so I do the rotations with the vectors, moving the position of the chest block, as well as rotating it. (I actually tried the Rotate function for the block itself with no success) #(utp=pitch, uth=heading, uty=yaw) cloc=UTOrigin+rotate(UTUnitAxis,utp,(1,0,0))*HeadDiameter/2 caxis=rotate( (HeadDiameter*2,0,0), utp,(1,0,0) ) #### !!!! Why doesn't this make the check pitch forward? caxis=rotate(caxis,uty,(0,0,1)) caxis=rotate(caxis,uth,(0,1,0)) Chest.pos=cloc Chest.axis=caxis As you can see from the code, for some reason the rotation that's supposed to happen about the long axis of the box doesn't. the strange thing is that the other ones work ok, so I'm not sure what I'm doing wrong. I've attached the code if you want to try and run it. The problem is on line 48. You'll notice that the arm doesn't follow the torso just yet, which is ok. Any ideas? Thanks! -kailas |
From: Ron A. <rr...@ro...> - 2008-02-06 22:04:13
Attachments:
ApolloBody.py
|
Kailas Narendran wrote: > > As you can see from the code, for some reason the rotation that's > supposed to happen about the long axis of the box doesn't. the strange > thing is that the other ones work ok, so I'm not sure what I'm doing > wrong. > > I've attached the code if you want to try and run it. The problem is on > line 48. You'll notice that the arm doesn't follow the torso just yet, > which is ok. > > Any ideas? I played around with your program a bit and found it easier to group parts in frames. Attached is what I got so far. I think this will be easier for you to extend. Cheers, Ron |
From: <bre...@un...> - 2008-02-06 22:20:50
|
Interesting and a nice "refactoring". I just started with vPython (but already know Python somewhat) and assumed that to create groups one would derive classes from frame, as shown. It seems to work, but is this not preferred/robust? import visual as v class Wheelset(v.frame): def __init__(self, xPos, whlRad=0.5, etc): v.frame.__init__(self, pos=(xPos,whlRad,0.0)) v.cylinder(frame=self, pos=(0,0,-0.5*axleLength), axis=(0.0, 0.0, axleLength), radius=axlRad) etc Ron Adam <rr...@ro...> Sent by: vis...@li... 07/02/2008 09:04 AM To vis...@li... cc pub...@ci... Subject Re: [Visualpython-users] Visual Python Help Kailas Narendran wrote: > > As you can see from the code, for some reason the rotation that's > supposed to happen about the long axis of the box doesn't. the strange > thing is that the other ones work ok, so I'm not sure what I'm doing > wrong. > > I've attached the code if you want to try and run it. The problem is on > line 48. You'll notice that the arm doesn't follow the torso just yet, > which is ok. > > Any ideas? I played around with your program a bit and found it easier to group parts in frames. Attached is what I got so far. I think this will be easier for you to extend. Cheers, Ron ______________________________________________________________________ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email ______________________________________________________________________""" Apollo Body """ import wx from visual import * from math import pi class Hand(object): color = color.green radius = .25 def __init__(self, parent, pos): self.obj = frame(frame=parent, pos=pos) sphere(frame=self.obj, radius=self.radius, color=self.color) class ForeArm(object): color = color.blue axis = (1, 0, 0) elboaxis = (0, 1, 0) radius = .2 def __init__(self, parent, pos): self.obj = frame(frame=parent, pos=pos) cylinder(frame=self.obj, axis=self.axis, radius=self.radius, color=self.color) self.bendpos = 0.0 def position(self, bend): # Elbo bend bend = pi * .5 + bend * .50 # Reduce range anglediff = self.bendpos - bend self.obj.rotate(angle=anglediff, axis=self.elboaxis) self.bendpos = bend class UpperArm(object): color = color.blue axis = (1, 0, 0) radius = .2 def __init__(self, parent, pos): self.obj = frame(frame=parent, pos=pos) cylinder(frame=self.obj, axis=self.axis, radius=self.radius, color=self.color) self.rollpos = 0.0 self.pitchpos = 0.0 self.headingpos = 0.0 def position(self, heading, pitch, roll): # Arm point heading *= .50 # Reduce range anglediff = self.headingpos - heading self.obj.rotate(angle=anglediff, axis=(0, 0, 1)) self.headingpos = heading # Arm raise pitch *= .50 # Reduce range anglediff = self.pitchpos - pitch self.obj.rotate(angle=anglediff, axis=(1, 0, 0)) self.pitchpos = pitch # Arm twist roll *= .90 # Reduce range anglediff = self.rollpos - roll self.obj.rotate(angle=anglediff, axis=(0, 1, 0)) self.rollpos = roll class Chest(object): color = color.red axis = (2, 0, 0) width = .75 def __init__(self, parent, pos): self.obj = frame(frame=parent, pos=pos) box(frame=self.obj, pos=(0,1,0), axis=self.axis, width=self.width, color=self.color) self.headingpos = 0.0 self.pitchpos = 0.0 self.yawpos = 0.0 def position(self, heading, pitch, yaw): # Turn Left or Right. heading *= .50 # Reduce range anglediff = self.headingpos - heading self.obj.rotate(angle=anglediff, axis=(0, 1, 0)) self.headingpos = heading # Bend forward or back. pitch *= .50 # Reduce range anglediff = self.pitchpos - pitch self.obj.rotate(angle=anglediff, axis=(1, 0, 0)) self.pitchpos = pitch # Lean left or right. yaw *= .10 # Reduce range anglediff = self.yawpos - yaw self.obj.rotate(angle=anglediff, axis=(0, 0, 1)) self.yawpos = yaw class Head(object): radius = .5 color = color.red def __init__(self, parent, pos): self.obj = frame(frame=parent, pos=pos) sphere(frame=self.obj, radius=self.radius, color=self.color) class Stomach(object): color = color.red width = .75 height = 1 length = 1.5 def __init__(self, parent, pos): self.obj = frame(frame=parent, pos=pos) box(frame=self.obj, width=self.width, height=self.height, length=self.length, color=self.color) # Build the body. # # Larger parts act as frames for smaller parts so # they rotate and move together. body = frame() stomach = Stomach(body, (0, 0, 0)) chest = Chest(stomach.obj, (0, .25, 0)) head = Head(chest.obj, (0, 2.25, 0)) upper_arm = UpperArm(chest.obj, (1.25, 1.5, 0)) fore_arm = ForeArm(upper_arm.obj, (1.25, 0, 0)) hand = Hand(fore_arm.obj, (1.5, 0, 0)) def position(utp, uty, uth, p, h, r, e): # Update body position. fore_arm.position(e) upper_arm.position(h, p, r) chest.position(uth, utp, uty) ID_ABOUT=101 ID_EXIT=110 class MainWindow(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,wx.ID_ANY, title, size = (400,600)) #self.control = wx.TextCtrl(self, 1, style=wx.TE_MULTILINE) self.CreateStatusBar() # A Statusbar in the bottom of the window panel = wx.Panel(self, -1) # Setting up the menu. filemenu= wx.Menu() filemenu.Append(ID_ABOUT, "&About"," Information about this program") filemenu.AppendSeparator() filemenu.Append(ID_EXIT,"E&xit"," Terminate the program") # Creating the menubar. menuBar = wx.MenuBar() # Adding the "filemenu" to the MenuBar menuBar.Append(filemenu, "&File") # Create the sliders font1 = wx.Font(15, wx.NORMAL, wx.ITALIC, wx.NORMAL) # Uppor torso pitch hboxutp = wx.BoxSizer(wx.HORIZONTAL) utpl = wx.StaticText(panel, -1, "Upper Torso Pitch", (45, 25), style=wx.ALIGN_CENTRE) utpl.SetFont(font1) hboxutp.Add(utpl, 1, wx.EXPAND) self.UpperTorsoPitch = wx.Slider(panel, -1, 0, -100, 100, wx.DefaultPosition, (10, -1), wx.SL_HORIZONTAL | wx.SL_LABELS) hboxutp.Add(self.UpperTorsoPitch,1,wx.EXPAND) # Upper torso yaw hboxuty = wx.BoxSizer(wx.HORIZONTAL) utyl = wx.StaticText(panel, -1, "Upper Torso Yaw", (45, 25), style=wx.ALIGN_CENTRE) utyl.SetFont(font1) hboxuty.Add(utyl, 1, wx.EXPAND) self.UpperTorsoYaw = wx.Slider(panel, -1, 0, -100, 100, wx.DefaultPosition, (10, -1), wx.SL_HORIZONTAL | wx.SL_LABELS) hboxuty.Add(self.UpperTorsoYaw,1,wx.EXPAND) # Upper torso heading hboxuth = wx.BoxSizer(wx.HORIZONTAL) uthl=wx.StaticText(panel, -1, "Upper Torso Heading", (45, 25), style=wx.ALIGN_CENTRE) uthl.SetFont(font1) hboxuth.Add(uthl, 1, wx.EXPAND) self.UpperTorsoHeading = wx.Slider(panel, -1, 0, -100, 100, wx.DefaultPosition, (10, -1), wx.SL_HORIZONTAL | wx.SL_LABELS) hboxuth.Add(self.UpperTorsoHeading,1,wx.EXPAND) # arm pitch hboxuap = wx.BoxSizer(wx.HORIZONTAL) uapl = wx.StaticText(panel, -1, "Upper Arm Roll", (45, 25), style=wx.ALIGN_CENTRE) uapl.SetFont(font1) hboxuap.Add(uapl, 1, wx.EXPAND) self.UpperArmPitch = wx.Slider(panel, -1, 0, -100, 100, wx.DefaultPosition, (10, -1), wx.SL_HORIZONTAL | wx.SL_LABELS) hboxuap.Add(self.UpperArmPitch, 1, wx.EXPAND) # Upper arm yaw hboxuay = wx.BoxSizer(wx.HORIZONTAL) uayl = wx.StaticText(panel, -1, "Upper Arm Yaw", (45, 25), style=wx.ALIGN_CENTRE) uayl.SetFont(font1) hboxuay.Add(uayl,1,wx.EXPAND) self.UpperArmYaw = wx.Slider(panel, -1, 0, -100, 100, wx.DefaultPosition, (10, -1), wx.SL_HORIZONTAL | wx.SL_LABELS) hboxuay.Add(self.UpperArmYaw, 1, wx.EXPAND) # Upper arm heading hboxuah = wx.BoxSizer(wx.HORIZONTAL) uahl = wx.StaticText(panel, -1, "Upper Arm Heading", (45, 25), style=wx.ALIGN_CENTRE) uahl.SetFont(font1) hboxuah.Add(uahl, 1, wx.EXPAND) self.UpperArmHeading = wx.Slider(panel, -1, 0, -100, 100, wx.DefaultPosition, (10, -1), wx.SL_HORIZONTAL | wx.SL_LABELS) hboxuah.Add(self.UpperArmHeading, 1, wx.EXPAND) # Elbow angle hboxe = wx.BoxSizer(wx.HORIZONTAL) el = wx.StaticText(panel, -1, "Elbow Angle", (45, 25), style=wx.ALIGN_CENTRE) el.SetFont(font1) hboxe.Add(el, 1, wx.EXPAND) self.ElbowAngle = wx.Slider(panel, -1, 0, -100, 100, wx.DefaultPosition, (10, -1), wx.SL_HORIZONTAL | wx.SL_LABELS) hboxe.Add(self.ElbowAngle, 1, wx.EXPAND) vbox = wx.BoxSizer(wx.VERTICAL) vbox.Add(hboxutp, 1, wx.EXPAND) vbox.Add(hboxuty, 1, wx.EXPAND) vbox.Add(hboxuth, 1, wx.EXPAND) vbox.Add(hboxuap, 1, wx.EXPAND) vbox.Add(hboxuay, 1, wx.EXPAND) vbox.Add(hboxuah, 1, wx.EXPAND) vbox.Add(hboxe, 1, wx.EXPAND) wx.EVT_MENU(self, ID_ABOUT, self.OnAbout) wx.EVT_MENU(self, ID_EXIT, self.OnExit) wx.EVT_COMMAND_SCROLL(self.ElbowAngle, self.ElbowAngle.GetId(), self.OnAngleSliderChange) wx.EVT_COMMAND_SCROLL(self.UpperArmPitch, self.UpperArmPitch.GetId(), self.OnAngleSliderChange) wx.EVT_COMMAND_SCROLL(self.UpperArmYaw, self.UpperArmYaw.GetId(), self.OnAngleSliderChange) wx.EVT_COMMAND_SCROLL(self.UpperArmHeading, self.UpperArmHeading.GetId(), self.OnAngleSliderChange) wx.EVT_COMMAND_SCROLL(self.UpperTorsoHeading, self.UpperTorsoHeading.GetId(), self.OnAngleSliderChange) wx.EVT_COMMAND_SCROLL(self.UpperTorsoPitch, self.UpperTorsoPitch.GetId(), self.OnAngleSliderChange) wx.EVT_COMMAND_SCROLL(self.UpperTorsoYaw, self.UpperTorsoYaw.GetId(), self.OnAngleSliderChange) panel.SetSizer(vbox) panel.SetAutoLayout(1) self.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content. self.Show(True) def OnAngleSliderChange(self, event): e = self.ElbowAngle.GetValue() p = self.UpperArmPitch.GetValue() h = self.UpperArmHeading.GetValue() r = self.UpperArmYaw.GetValue() utp = self.UpperTorsoPitch.GetValue() uty = self.UpperTorsoYaw.GetValue() uth = self.UpperTorsoHeading.GetValue() e= e / 100.0 * pi p= p / 100.0 * pi h= h / 100.0 * pi r= r / 100.0 * pi utp = utp / 100.0 * pi uty = uty / 100.0 * pi uth = uth / 100.0 * pi position(utp, uty, uth, p, h, r, e) def OnAbout(self, event): # Create a message dialog box d= wx.MessageDialog( self, " A sample editor \n" " in wxPython","About Sample Editor", wx.OK) d.ShowModal() # Shows it d.Destroy() # finally destroy it when finished. def OnExit(self, event): self.Close(True) # Close the frame. app = wx.PySimpleApp() frame = MainWindow(None, -1, "Apollo Body Control Panel") app.MainLoop() ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Visualpython-users mailing list Vis...@li... https://lists.sourceforge.net/lists/listinfo/visualpython-users UNITED GROUP This email message is the property of United Group. The information in this email is confidential and may be legally privileged. It is intended solely for the addressee. Access to this email by anyone else is unauthorised. If you are not the intended recipient, you may not disclose, copy or distribute this email, nor take or omit to take any action in reliance on it. United Group accepts no liability for any damage caused by this email or any attachments due to viruses, interference, interception, corruption or unauthorised access. If you have received this email in error, please notify United Group immediately by email to the sender's email address and delete this document. |
From: Ron A. <rr...@ro...> - 2008-02-07 02:00:44
|
bre...@un... wrote: > > Interesting and a nice "refactoring". Thanks :-) > I just started with vPython (but already know Python somewhat) and > assumed that to create groups one would derive classes from frame, as > shown. It seems to work, but is this not preferred/robust? > > import visual as v > > class Wheelset(*v.frame*): > > def __init__(self, xPos, whlRad=0.5, /etc/): > > *v.frame.__init__(self,* pos=(xPos,whlRad,0.0)*)* > > v.cylinder(*frame=self*, pos=(0,0,-0.5*axleLength), > axis=(0.0, 0.0, axleLength), radius=axlRad) > etc When I tried a variation of the above with the Head() object, the class color attribute was overwritten. The defaults could be moved to within the __init__ method, but then you may have the opposite problem of overwriting a frame attribute or method without knowing it. So I think if there are a lot of methods or attributes, using a container obj makes it easier to avoid name clashes. But it looks like, either way is ok. Ron |