Changes between Version 2 and Version 3 of Tutorials


Ignore:
Timestamp:
Mar 7, 2016, 1:34:53 PM (10 years ago)
Author:
fma
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Tutorials

    v2 v3  
    1515== Simple example ==
    1616
    17 As '''Py4bot''' is just a framework, it is up to you to write the application matching your rogot. But don't worry, it is very easy.
    18 
    19 For this example, we are going to setup an application for a 3DoF hexapod. This hexapod will use a [http://www.dfrobot.com/wiki/index.php/Veyron_Servo_Driver_(24-Channel)_(SKU:DRI0029) Veryon servo driver], from DFRobot, as this driver is fully supported by Py4bot. To control this hexapod, we are going to use a [http://www.thrustmaster.com/en_IN/products/firestorm-dual-analog-3 Thrustmaster Firestorm Dual Analog 3] gamepad.
     17'''Py4bot''' is just a framework, so it is up to you to write the application matching your robot. But don't worry, it is very easy.
     18
     19As Py4bot has a nice 3D simulation engine, based on [http://vpython.org VPython], for this example, we are going to setup an application for a simulated 3DoF hexapod.
     20
     21To control the simulation, we are going to use a [http://www.thrustmaster.com/en_IN/products/firestorm-dual-analog-3 Thrustmaster Firestorm Dual Analog 3] gamepad.
    2022
    2123All usefull classes are available from the '''{{{api.py}}}''' module. So, we just have to import things from here. Let's create a '''{{{hexapod.py}}}''' file to put our code, and import what we are going to use in this tutorial:
     
    2628# -*- coding: utf-8 -*-
    2729
    28 from py4bot.api import Logger
    29 from py4bot.api import GaitFactory, GaitManager, GaitSequencer
    30 from py4bot.api import Robot, Body
    31 from py4bot.api import ActuatorPool, ServoPool, Veyron
    32 from py4bot.api import Leg3DofIk, Leg3Dof, Coxa, Femur, Tibia
    33 from py4bot.api import RemoteControl, FrontendFactory
    34 from py4bot.api import MapperSet, MapperSetValue, MapperWalk
    35 }}}
    36 
    37 Now, let's create the robot! A multi-legs robot is mainly build from a body, and several legs. In most cases, the defaut body provided by Py4bot is OK, but in any case, we need to create legs. The second thing we also need to create is the ''actuator pool'', which contain all legs joints. In our example, joints are standard servos. So, here is what the main robot class looks like:
     30from py4bot import api as api4bot
     31}}}
     32
     33Now, let's create the robot! A multi-legs robot is mainly build from a body, and several legs. In most cases, the defaut body provided by Py4bot is OK, but in any case, we need to create legs.
     34
     35The second thing we also need to create is the ''actuator pool'', which contain all legs joints. In our example, joints are standard servos. So, here is what the main robot class looks like:
    3836
    3937{{{
     
    4341
    4442
    45 class Hexapod(Robot):
     43class Hexapod(api4bot.Robot):
    4644    def _createLegs(self):
    47         legIk = Leg4DofIk(settings.LEGS_GEOMETRY)
    48 
    4945        legs = {}
    5046        legIk = {}
    5147        for legIndex in settings.LEGS_INDEX:
    52             legs[legIndex] = Leg4Dof(legIndex, {'coxa': Coxa(), 'femur': Femur(), 'tibia': Tibia()})
    53             legIk[legIndex] = Leg4DofIk(settings.LEGS_GEOMETRY[legIndex])
     48            legs[legIndex] = api4bot.Leg3Dof(legIndex, {'coxa': Coxa(), 'femur': Femur(), 'tibia': Tibia()})
     49            legIk[legIndex] = api4bot.Leg3DofIk(settings.LEGS_GEOMETRY[legIndex])
    5450
    5551        return legs, legIk
    5652
    5753    def _createActuatorPool(self):
    58         driver = Veyron("/dev/ttyACM0", 57600)
    59 
    60         pool = ServoPool(driver)
     54        driver = api4bot.VPython3Dof(settings.LEGS_INDEX, settings.LEGS_GEOMETRY, settings.LEGS_ORIGIN, settings.LEGS_SERVOS_MAPPING)
     55        pool = api4bot.ActuatorPool(driver)
     56
    6157        for leg in self._legs.values():
    6258
    6359            # Create joints actuators
    6460            num = settings.LEGS_SERVOS_MAPPING[leg.index]['coxa']
    65             servo = pool.create(leg.coxa, num, **settings.SERVOS_CALIBRATION[num])
    66             pool.add(servo)
     61            actuator = pool.create(leg.coxa, num)
     62            pool.add(actuator)
    6763
    6864            num = settings.LEGS_SERVOS_MAPPING[leg.index]['femur']
    69             servo = pool.create(leg.femur, num, **settings.SERVOS_CALIBRATION[num])
    70             pool.add(servo)
     65            actuator = pool.create(leg.femur, num)
     66            pool.add(actuator)
    7167
    7268            num = settings.LEGS_SERVOS_MAPPING[leg.index]['tibia']
    73             servo = pool.create(leg.tibia, num, **settings.SERVOS_CALIBRATION[num])
    74             pool.add(servo)
    75 
     69            actuator = pool.create(leg.tibia, num)
     70            pool.add(actuator)
    7671        return pool
    7772}}}
    7873
    7974
    80 As you can see, we just implemented 2 virtual methods, '''{{{_createLegs()}}}''' and '''{{{_createActuatorPool()}}}'''. Also note that we used some values from the '''{{{settings.py}}}''' module. This module is just a way to centralise the configuration of our hexapod. For now, it should contain s omething like:
     75As you can see, we just implemented 2 virtual methods, '''{{{_createLegs()}}}''' and '''{{{_createActuatorPool()}}}'''.
     76
     77Also note that we used some values from the '''{{{settings.py}}}''' module. This module is just a simple way to centralise the configuration of our hexapod.
     78
     79For now, it should contain something like:
    8180
    8281{{{
     
    8584# -*- coding: utf-8 -*-
    8685
    87 import math
    88 
    89 from py4bot.api import config
     86from py4bot import api as api4bot
    9087
    9188
     
    112109    'RR': {'x':  35., 'y': -80., 'gamma0' : 330.},
    113110}
    114 config.initOrigin(LEGS_INDEX, LEGS_ORIGIN)
     111api4bot.config.initOrigin(LEGS_INDEX, LEGS_ORIGIN)
    115112
    116113# Legs (feet) neutral position (femur horizontal, tibia vertical)
     
    141138    }
    142139}
    143 config.initNeutral(LEGS_INDEX, LEGS_NEUTRAL)
     140api4bot.config.initNeutral(LEGS_INDEX, LEGS_NEUTRAL)
    144141
    145142# Legs / servos mapping
     
    152149    'LF': {'coxa': 23, 'femur': 22, 'tibia': 21}
    153150}
    154 
    155 # Servos calibration
    156 SERVOS_CALIBRATION = {
    157      0: {'pulse90': 1500, 'ratio': 1000./90.},  # tibia leg RF
    158      1: {'pulse90': 1500, 'ratio': 1000./90.},  # femur leg RF
    159      2: {'pulse90': 1500, 'ratio': 1000./90.},  # coxa leg RF
    160      3: {'pulse90': 1500, 'ratio': 1000./90.},  # free
    161 
    162      4: {'pulse90': 1500, 'ratio': 1000./90.},  # tibia leg RM
    163      5: {'pulse90': 1500, 'ratio': 1000./90.},  # femur leg RM
    164      6: {'pulse90': 1500, 'ratio': 1000./90.},  # coxa leg RM
    165      7: {'pulse90': 1500, 'ratio': 1000./90.},  # free
    166 
    167      8: {'pulse90': 1500, 'ratio': 1000./90.},  # tibia leg RR
    168      9: {'pulse90': 1500, 'ratio': 1000./90.},  # femur leg RR
    169     10: {'pulse90': 1500, 'ratio': 1000./90.},  # coxa leg RR
    170     11: {'pulse90': 1500, 'ratio': 1000./90.},  # free
    171 
    172     12: {'pulse90': 1500, 'ratio': 1000./90.},  # free
    173     13: {'pulse90': 1500, 'ratio': 1000./90.},  # tibia leg LR
    174     14: {'pulse90': 1500, 'ratio': 1000./90.},  # femur leg LR
    175     15: {'pulse90': 1500, 'ratio': 1000./90.},  # coxa leg LR
    176 
    177     16: {'pulse90': 1500, 'ratio': 1000./90.},  # free
    178     17: {'pulse90': 1500, 'ratio': 1000./90.},  # tibia leg LM
    179     18: {'pulse90': 1500, 'ratio': 1000./90.},  # femur leg LM
    180     19: {'pulse90': 1500, 'ratio': 1000./90.},  # coxa leg LM
    181 
    182     20: {'pulse90': 1500, 'ratio': 1000./90.},  # free
    183     21: {'pulse90': 1500, 'ratio': 1000./90.},  # tibia leg RM
    184     22: {'pulse90': 1500, 'ratio': 1000./90.},  # femur leg RM
    185     23: {'pulse90': 1500, 'ratio': 1000./90.},  # coxa leg RM
    186 }
    187 }}}
     151}}}
     152
     153Some of these values seem obvious, some don't; we'll discuss all this later.
     154
     155Now, let's create our robot. In '''{{{hexapod.py}}}''', add:
     156
     157{{{
     158#!python
     159
     160def main():
     161    robot = Hexapod()
     162}}}
     163
     164The main interrest of a multi-legs robot is to make it walk! But by default, the '''{{{Robot}}}''' class does not know any '''gait''', so, we have to teach it how to actually walk.
     165
     166Again, as Py4bot is a framework, it comes with some pre-defined gaits. So, all we have to do is to tell our robot which gaits to use (at least one), and give some params:
     167
     168{{{
     169#!python
     170
     171    for gaitName in settings.GAITS:
     172        legsIndexGroups = settings.GAIT_LEGS_GROUPS[gaitName]
     173        gaitParams = settings.GAIT_PARAMS[gaitName]
     174        gait = api4bot.GaitFactory().create(gaitName, legsIndexGroups, gaitParams)
     175        api4bot.GaitManager().add(gait)
     176}}}
     177
     178Let's see what wee need to add in the '''{{{settings.py}}}''' module:
     179
     180{{{
     181#!python
     182
     183# Gaits definitions
     184GAITS = ("tripod", "tetrapod", "riple", "metachronal", "wave")
     185
     186GAIT_LEGS_GROUPS = {
     187    'tripod':      (('RM', 'LF', 'LR'), ('RF', 'LM', 'RR')),
     188    'tetrapod':    (('RR', 'LM'), ('RF', 'LR'), ('RM', 'LF')),
     189    'riple':       (('RR',), ('LM',), ('RF',), ('LR',), ('RM',), ('LF',)),
     190    'metachronal': (('RR',), ('LM',), ('RF',), ('LR',), ('RM',), ('LF',)),
     191    'wave':        (('RR',), ('RM',), ('RF',), ('LR',), ('LM',), ('LF',))
     192}
     193
     194GAIT_PARAMS = {
     195    'tripod': {'length': 40., 'angle': 10., 'height': 40., 'minLength': 4., 'minAngle': 2., 'speedMin':  50., 'speedMax': 200.},
     196    'tetrapod': {'length': 40., 'angle': 10., 'height': 30., 'minLength': 4., 'minAngle': 2., 'speedMin':  50., 'speedMax': 200.},
     197    'riple': {'length': 40., 'angle': 10., 'height': 30., 'minLength': 4., 'minAngle': 2., 'speedMin':  50., 'speedMax': 300.},
     198    'metachronal': {'length': 40., 'angle': 10., 'height': 30., 'minLength': 4., 'minAngle': 2., 'speedMin':  50., 'speedMax': 200.},
     199    'wave': {'length': 40., 'angle': 10., 'height': 30., 'minLength': 4., 'minAngle': 2., 'speedMin':  50., 'speedMax': 200.}
     200}
     201}}}
     202
     203
     204
     205
     206
     207
     208
    188209
    189210