Example #1
0
class Scene:
    def __init__(self):
        self.geometries = []
        self.world = World()
        self.world.setGravity((0, -9.8, 0))
        self.world.setERP(0.4)
        self.world.setCFM(1E-5)
        self.space = Space()
        self.contact_group = JointGroup()
        self.update_callbacks = []

    def add_geometry(self, geometry):
        self.geometries.append(geometry)

    def simulate(self, delta=0.04, duration=2.0, callback=None):
        time = 0.0
        collision_iterations = 4
        while time < duration:
            for i in range(collision_iterations):
                # Detect collisions and create contact joints
                self.space.collide((), self.near_callback)

                # Simulate the world
                self.world.step(delta / collision_iterations)

                # Remove contact joints
                self.contact_group.empty()
            time += delta

            for update_callback in self.update_callbacks:
                update_callback(time)
            if callback is not None:
                callback(time)

    def near_callback(self, _, geom1, geom2):
        # Check if the objects do collide
        contacts = collide(geom1, geom2)

        # Create contact joints
        for contact in contacts:
            contact.setBounce(0.01)
            contact.setMu(2000)
            joint = ContactJoint(self.world, self.contact_group, contact)
            joint.attach(geom1.getBody(), geom2.getBody())

    def visualize(self, delta=0.04, duration=2.0, callback=None):
        visualizer = Visualizer()
        visualizer.create_window()
        for geometry in self.geometries:
            visualizer.add_geometry(geometry)
        self.simulate(delta,
                      duration,
                      callback=VisualizationUpdater(visualizer, callback))
        visualizer.destroy_window()

    def on_update(self, callback):
        self.update_callbacks.append(callback)
Example #2
0
 def __init__(self, world: ode.World = None):
     """
     Args:
         world: A py3ode :class:`World` object. If not provided, a new one will be
             created with gravity ``(0,-9.81,0)``.
     """
     if world is None:
         world = ode.World()
         world.setGravity((0, -9.81, 0))
     self.world = world
     self.maxStepSize = 0.05
     self._lastUpdateSimTime = SimMan.now
     SimMan.process(self._stateUpdater())
Example #3
0
class odeRTB:
    def __init__(self, gui):
        self.gui = gui

        self.vDHistory = []
        self.bPHistory = []

        self.th = TimeHelper()

        self.w = World()
        self.w.setGravity((0.0, 0.0, 0.0))
        self.b = Body(self.w)
        self.b.setPosition((0.0, 0.0, 0.0))

        self.lt = self.th.getTimestamp(microsec=True)
        self.lastVal = None

    def plotAnimate(self, i):
        xs = []
        ys = []
        zs = []
        for v in self.bPHistory[:-10]:
            xs.append(v[0])
            ys.append(v[1])
            zs.append(v[2])

        if len(self.bPHistory) > 500:
            self.bPHistory.pop(0)
            self.vDHistory.pop(0)

        self.ax1.clear()
        r = np.array(xs)
        s = np.array(ys)
        t = np.array(zs)
        self.ax1.scatter(r, s, zs, marker='o')

    def startPltShow(self, a=''):

        self.fig = plt.figure()
        self.ax1 = self.fig.add_subplot(111, projection='3d')

        ani = animation.FuncAnimation(self.fig, self.plotAnimate, interval=500)
        plt.show()

    iter = 0

    def update(self, fromWho, val):
        #print("ode.updateIt",fromWho)
        self.iter += 1
        if fromWho == 'accel':

            if len(self.vDHistory) == 10:
                _thread.start_new(self.startPltShow, ())
            t = self.th.getTimestamp(microsec=True)
            if self.lastVal == None:
                self.lastVal = val
            else:
                vD = []
                for k in range(len(val)):
                    vD.append(self.lastVal[k] - val[k])
                self.vDHistory.append(vD)
                #print(t-self.lt,"    mm/s^2:",vD)
                #if (self.iter%100)==0:
                #    self.b.setLinearVel((0.0,0.0,.0))
                #    print("0.0.0")
                bp = self.b.getPosition()
                self.bPHistory.append(bp)
                #print("b pos: {}    {}    {}".format(
                #    round(bp[0], 4),
                #    round(bp[1], 4),
                #    round(bp[2], 4)
                #    ))
                avgFrom = 100
                if len(self.vDHistory) % avgFrom == 0:
                    print("recall avg")
                    vcc = [0.0, 0.0, 0.0]
                    for ii in range(avgFrom - 1):
                        vcc[0] += self.vDHistory[ii][0]
                        vcc[1] += self.vDHistory[ii][1]
                        vcc[2] += self.vDHistory[ii][2]
                    vcc[0] /= float(avgFrom - 1.0)
                    vcc[1] /= float(avgFrom - 1.0)
                    vcc[2] /= float(avgFrom - 1.0)
                    self.va = vcc
                    vc = val
                elif len(self.vDHistory) > avgFrom:
                    vc = [
                        val[0] - self.va[0], val[1] - self.va[1],
                        val[2] - self.va[2]
                    ]

                    #print("va:",self.va)

                else:
                    vc = val

            # print("t",(t-self.lt)/1000000.0)

            #print("vdh",len(self.vDHistory)," -",vc)

                if len(self.vDHistory) > avgFrom + 10:
                    self.w.setGravity((
                        vD[0],  #vc[0],#vD[0],
                        vD[1],  #vc[1],#vD[1],
                        vD[2]  #vc[2]#vD[2]
                    ))

                #self.w.step( (t-self.lt)/1000000.0 )
                self.w.step(0.1)

                self.lastVal = val
                self.lt = t
Example #4
0
class Simulator(object):

    def __init__(self, Stable, wm, quad_pos=(0, 0, 0)):
        self.world = World()
        self.world.setGravity((0, -9.81, 0))
        self.space = Space()
        self.contactgroup = JointGroup()
        self.wm = wm

        # draw floor
        self.floor = GeomPlane(self.space, (0, 1, 0), -1)
        box(pos=(0, -1, 0), width=2, height=0.01, length=2)

        # Draw Quad
        self.quad = Quad(self.world, self.space, pos=quad_pos)

        # Init Algorithm
        self.stable = Stable(self.quad)

        # stop autoscale of the camera
        scene.autoscale = False

        # Initial noise
        #quad.motors[2].addForce((0.5, 1, 0))

    # Collision callback
    def near_callback(self, args, geom1, geom2):
        """Callback function for the collide() method.
        This function checks if the given geoms do collide and
        creates contact joints if they do.
        """
        # Check if the objects do collide
        contacts = collide(geom1, geom2)

        # Create contact joints
        world, contactgroup = args
        for c in contacts:
            c.setBounce(0.2)
            c.setMu(5000)
            j = ContactJoint(world, contactgroup, c)
            j.attach(geom1.getBody(), geom2.getBody())


    def step(self):
        # Control Quad if controls are enabled
        res = self.wii_remote()

        # Detect collisions
        self.space.collide((self.world, self.contactgroup), self.near_callback)
        # run algorithm
        self.stable.step()
        self.world.step(self.dt)
        self.contactgroup.empty()

        # point camera to quad
        scene.center = self.quad.pos
        self.print_log()
        return res

    def wii_remote(self):
        if self.wm:
            if self.wm.state['buttons'] & cwiid.BTN_LEFT:
                self.stable.command_yaw = 1
            if self.wm.state['buttons'] & cwiid.BTN_RIGHT:
                self.stable.command_yaw = -1
            if self.wm.state['buttons'] & cwiid.BTN_1:
                self.stable.command_acceleration = 1
            if self.wm.state['buttons'] & cwiid.BTN_2:
                self.stable.command_acceleration = -1
            if self.wm.state['buttons'] & cwiid.BTN_A and self.wm.state['acc']:
                p = (wm.state['acc'][1] - 125.) / 125.
                r = (wm.state['acc'][0] - 125.) / 125.
                self.stable.command_pitch = -p
                self.stable.command_roll = r
            if self.wm.state['buttons'] & cwiid.BTN_B and self.wm.state['acc']:
                a = (wm.state['acc'][1] - 125.) / 125.
                self.stable.command_acceleration = a * 10
            if self.wm.state['buttons'] & cwiid.BTN_HOME:
                self.wm.close()
                return True
            if not self.wm.state['buttons']:
                self.stable.command_pitch = 0
                self.stable.command_roll = 0
                self.stable.command_yaw = 0
                self.stable.command_acceleration = 0
        return False

    def print_log(self):
        print "%1.2fsec: pos=(%6.3f, %6.3f, %6.3f) vel=(%6.3f, %6.3f, %6.3f) pry=(%6.3f, %6.3f, %6.3f)" % \
              (self.total_time, self.quad.pos[0], self.quad.pos[1], self.quad.pos[2],
                        self.quad.vel[0], self.quad.vel[1], self.quad.vel[2],
                        self.quad.pitch, self.quad.roll, self.quad.yaw)
        print "power=(%6.3f, %6.3f, %6.3f, %6.3f)" % \
            (self.quad.motors_force[0], self.quad.motors_force[1],
             self.quad.motors_force[2], self.quad.motors_force[3])

    def simulate(self):
        # Do the simulation...
        self.total_time = 0.0
        self.dt = 0.04
        self.stop = False
        while not self.stop:
            rate(self.dt*1000)
            self.step()
            self.total_time += self.dt
Example #5
0
        rforce = -self.v1*(self.motors_force[3]+m_noise[3])*rotational_factor
        self.motors[3].addForce(rforce)


    @property
    def vel(self):
        return self.center.getLinearVel()



######################################
# Simulation test

if __name__ == '__main__':
    world = World()
    world.setGravity((0, -9.81, 0))
    world.setERP(0.8)
    world.setCFM(1E-5)
    space = Space()
    contactgroup = JointGroup()


    # Set environment
    floor = GeomPlane(space, (0, 1, 0), -1)
    box(pos=(0, -1, 0), width=2, height=0.01, length=2)

    quad = Quad(world, space, pos=(0, -0.5, 0))

    # set initial state of motors
    # quad.motors_noise = (0, 0, 0, 0)
    quad.motors_force = (1.92, 1.92, 1.92, 1.92)