2

| drake 0.38.0 | python 3.7 | OS: ubuntu 20.04 | pycharm |

I want to use a sine wave (amplitude: 0.01, f: 2) as the joint torque input for the base of a kuka iiwa simulated robot. (i.e. I just want to see the base swivel back and forth to test some other code)

I used the Sine system builder to add a sine system to my diagram.

sine = builder.AddSystem(Sine(np.array([0.01]),np.array([2]),np.array([0])))
context = diagram.CreateDefaultContext()
sine_context = sine.GetMyMutableContextFromRoot(context)
## sine_context = sine.CreateDefaultContext() # exact same behavior occurs

...
qt = np.zeros(n_dof)
qt[0] = sine.get_output_port(0).Eval(sine_context)
plant.get_actuation_input_port().FixValue(plant_context, qt)

when I call the below (at some time t) and attempt to graph qt[0], I see three waves instead of one: sine, cosine, and something else out of phase. My understanding is that Sine()'s output port 0 = sine, 1 = cosine, 2 = -sine and that I must use qt[0] = sine.get_output_port(0).Eval(sine_context) to get the floating point value of sine at a given time t.

simulator = Simulator(diagram, context)
simulator.set_target_realtime_rate(1.0)
# Advance the simulation slightly to initialize the GUI
simulator.AdvanceTo(0.01)
...
ml = momentum_log(5000, plant)
simulator.set_monitor(partial(momentum_log.monitor, ml))
while meshcat.GetButtonClicks(stop_sim_button) < 1:
      t = simulator.get_context().get_time()
      sine_context.SetTime(t)
      qt[0] = sine.get_output_port(0).Eval(sine_context)
      plant.get_actuation_input_port().FixValue(plant_context, qt)
      plotp(t,qt[0],0.05)
      simulator.AdvanceTo(t + 1.0)

ml.save()
plotp(t,qt[0],0.05)
plt.show()

What am I missing?

Edit: Please see below graph for clarification

Graph with mutlicolored dots shows the progression of a sine wave, cosine wave, and other, out of-phase wave from 0 - 50 seconds. Amplitude of the waves is 0.01 per the settings used.

L Wall
  • 65
  • 4

2 Answers2

2

The plot looks correct. When you sample sin(x) every 2 radians, that's what it should look like:

import matplotlib.pyplot as plt
from math import sin

amplitude = 0.01
frequency = 2.0
t = list(range(0, 50))
y = [amplitude * sin(frequency * x) for x in t]
plt.plot(t, y, 'ro')
plt.show()

output plot

jwnimmer-tri
  • 1,994
  • 2
  • 5
  • 6
0

When I run this sample code:

sine = Sine(np.array([0.01]), np.array([2]), np.array([0]))
context = sine.CreateDefaultContext()
value = sine.get_output_port(0).Eval(context)
print(repr(value))
context.SetTime(0.7)
value = sine.get_output_port(0).Eval(context)
print(repr(value))

then the printouts I see are this:

array([0.])
array([0.0098545])

That seems correct to me.

You'll need to provide a more thorough (i.e., complete) reproduction sample code in order to answer this question.

jwnimmer-tri
  • 1,994
  • 2
  • 5
  • 6
  • I took your code and integrated the changes into my code and I got the same 3-wave result. Does using a simulator alter the behavior of Sine? – L Wall May 25 '22 at 14:33
  • That plot looks to me exactly what I expect for plotting `sin(2t)` vs `t` at 1-second intervals. Did you intend to specify 2 radians per second? – jwnimmer-tri May 25 '22 at 14:45
  • I can run your code on it's own and get a single wave: def plotp(t,sin,pause): plt.scatter(t,sin) plt.pause(pause) def main(): sine = Sine(np.array([0.01]), np.array([2]), np.array([0])) context = sine.CreateDefaultContext() value = sine.get_output_port(0).Eval(context) t = np.arange(1,50,0.1) for x in t: context.SetTime(x) value = sine.get_output_port(0).Eval(context) plotp(x, value, 0.05) if __name__ == '__main__': main() but not my own code. which plot are you referring to? – L Wall May 25 '22 at 14:51
  • I made a new answer. – jwnimmer-tri May 25 '22 at 16:42