{"id":5291,"date":"2022-09-07T13:54:58","date_gmt":"2022-09-07T17:54:58","guid":{"rendered":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/?p=5291"},"modified":"2022-09-07T13:54:59","modified_gmt":"2022-09-07T17:54:59","slug":"servo-motion-with-pico-hw-saloni-gandhi","status":"publish","type":"post","link":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/2022\/09\/07\/servo-motion-with-pico-hw-saloni-gandhi\/","title":{"rendered":"Servo Motion with Pico HW: Saloni Gandhi"},"content":{"rendered":"\n<p><strong>Choreographic Intent:<\/strong><\/p>\n\n\n\n<p>I created a pattern of oscillation to the main line of the song &#8220;I will always love you&#8221; by Whitney Houston. My main intent was to recreate the beat of this song using the sound of the servo motions.<\/p>\n\n\n\n<p><strong>Code:<\/strong><\/p>\n\n\n\n<p>print(&#8220;Starting servo_sweep script.&#8221;)<\/p>\n\n\n\n<p>import math, time<br>import board<br>import pwmio<\/p>\n\n\n\n<h1>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<\/h1>\n\n\n\n<p>class Servo():<br>def <strong>init<\/strong>(self, pin, pulse_rate=50):<br>self.pwm = pwmio.PWMOut(board.GP0, duty_cycle=0, frequency=pulse_rate)<\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n    # Save the initialization arguments within the object for later reference.\n    self.pin = pin\n    self.pulse_rate = pulse_rate\n\n    # Initialize the other state variables.\n    self.target = None    # target angle; None indicates the &quot;OFF&quot; state\n    self.debug = False    # flag to control print output\n\ndef write(self, angle):\n\n    # calculate the desired pulse width in units of seconds\n    if angle is None:\n        pulse_width = 0.0\n    else:\n        pulse_width  = 0.001 + angle * (0.001 \/ 180.0)\n\n    # calculate the duration in seconds of a single pulse cycle\n    cycle_period = 1.0 \/ self.pulse_rate\n\n    # calculate the desired ratio of pulse ON time to cycle duration\n    duty_cycle   = pulse_width \/ cycle_period\n\n    # convert the ratio into a 16-bit fixed point integer\n    duty_fixed   = int(2**16 * duty_cycle)\n\n    # limit the ratio range and apply to the hardware driver\n    self.pwm.duty_cycle = min(max(duty_fixed, 0), 65535)\n\n    # save the target value in the object attribute (i.e. variable)\n    self.target = angle\n\n    # if requested, print some diagnostics to the console\n    if self.debug:\n        print(f&quot;Driving servo to angle {angle}&quot;)\n        print(f&quot; Pulse width {pulse_width} seconds&quot;)\n        print(f&quot; Duty cycle {duty_cycle}&quot;)\n        print(f&quot; Command value {self.pwm.duty_cycle}\\n&quot;)\n<\/pre>\n\n\n<h1>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<\/h1>\n\n\n\n<p>def linear_move(servo, start, end, speed=60, update_rate=50):<br># Calculate the number of seconds to wait between target updates to allow<br># the motor to move.<br># Units: seconds = 1.0 \/ (cycles\/second)<br>interval = 1.0 \/ update_rate<\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n# Compute the size of each step in degrees.\n# Units:  degrees = (degrees\/second) * second\nstep = speed * interval\n\n# Output the start angle once before beginning the loop.  This guarantees at\n# least one angle will be output even if the start and end are equal.\nangle = start\nservo.write(angle)\n\n# Loop once for each incremental angle change.\nwhile angle != end:\n    time.sleep(interval)            # pause for the sampling interval\n\n    # Update the target angle.  The positive and negative movement directions\n    # are treated separately.\n    if end &amp;gt;= start:\n        angle += step;              # movement in the positive direction\n        if angle &amp;gt; end:\n            angle = end             # end at an exact position\n    else:\n        angle -= step               # movement in the negative direction\n        if angle &lt; end:\n            angle = end             # end at an exact position\n\n    servo.write(angle)              # update the hardware\n<\/pre>\n\n\n<h1>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<\/h1>\n\n\n\n<p>def ringing_move(servo, q_d, q=0.0, qd=0.0, k=4<em>math.pi<\/em>math.pi, b=2.0,<br>update_rate=50, duration=2.0, debug=False):<\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ninterval = 1.0 \/ update_rate\n\nwhile duration &amp;gt; 0.0:\n    # Calculate the acceleration.\n    #   qdd         acceleration in angles\/sec^2\n    #   k           spring constant relating the acceleration to the angular displacement\n    #   b           damping constant relating the acceleration to velocity\n    qdd = k * (q_d - q) - b * qd\n\n    # integrate one time step using forward Euler integration\n    q  += qd  * interval    # position changes in proportion to velocity\n    qd += qdd * interval    # velocity changes in proportion to acceleration\n\n    # update the servo command with the new angle\n    servo.write(q)\n\n    # print the output for plotting if requested\n    if debug:\n        print(q)\n\n\n    time.sleep(interval)\n\n    duration -= interval\n<\/pre>\n\n\n<h1>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<\/h1>\n\n\n\n<h1>Create an object to represent a servo on the given hardware pin.<\/h1>\n\n\n\n<p>print(&#8220;Creating servo object.&#8221;)<br>servo = Servo(board.GP0)<\/p>\n\n\n\n<p>print(&#8220;Starting main script.&#8221;)<br>while True:<br># initial pause<br>time.sleep(2.0)<\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nprint(&quot;Starting ringing motions.&quot;)\n#and\nringing_move(servo, 90.0, duration=1)\n#i\nringing_move(servo, 45.0, duration=1)\n#e\nringing_move(servo, 90.0, duration=1)\nprint(&quot;Starting linear motions.&quot;)\n#i\nlinear_move(servo, 0.0, 180.0, speed=45)\n\n#will\nringing_move(servo, 90.0, duration=1)\n#al\nringing_move(servo, 45.0, duration=1)\n#ways\nlinear_move(servo, 180.0, 0.0, speed=45)\n#love\nringing_move(servo, 90.0, duration=1)\n#you\nlinear_move(servo, 0.0, 180.0, speed=45)\n\n# final pause\ntime.sleep(2.0)\n<\/pre>","protected":false},"excerpt":{"rendered":"<p>Choreographic Intent: I created a pattern of oscillation to the main line of the song &#8220;I will always love you&#8221; by Whitney Houston. My main intent was to&#8230;<\/p>\n","protected":false},"author":56,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/wp-json\/wp\/v2\/posts\/5291"}],"collection":[{"href":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/wp-json\/wp\/v2\/users\/56"}],"replies":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/wp-json\/wp\/v2\/comments?post=5291"}],"version-history":[{"count":1,"href":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/wp-json\/wp\/v2\/posts\/5291\/revisions"}],"predecessor-version":[{"id":5292,"href":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/wp-json\/wp\/v2\/posts\/5291\/revisions\/5292"}],"wp:attachment":[{"href":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/wp-json\/wp\/v2\/media?parent=5291"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/wp-json\/wp\/v2\/categories?post=5291"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/16-223\/f2022\/work\/wp-json\/wp\/v2\/tags?post=5291"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}