Changes between Version 9 and Version 10 of Tutorial5AdvancedRemoteControlUsage
- Timestamp:
- Nov 23, 2017, 9:39:16 AM (8 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Tutorial5AdvancedRemoteControlUsage
v9 v10 1 1 = Tutorial 5: Advanced remote control usage = 2 2 3 As we've seen in [wiki:Tutorial1FirstRobot tutorial 1], we created a {{{Gamepad}}} class in order to control our robot. This class inherits from {{{RemoteControl}}}, and implements a few virtual methods. As an example, we will use my setup for my big 4 DoF hexapod, '''Cronos''' :3 As we've seen in [wiki:Tutorial1FirstRobot tutorial 1], we created a {{{Gamepad}}} class in order to control our robot. This class inherits from {{{RemoteControl}}}, and implements a few virtual methods. As an example, we will use my setup for my big 4 DoF hexapod, '''Cronos'''. We just create a class which inherits from {{{RemoteControl}}}: 4 4 5 5 {{{ … … 9 9 def _createFrontend(self): 10 10 return Thrustmaster(THRUSTMASTER_PATH) 11 }}} 12 13 The method {{{_createFrontend()}}} must return a valid {{{Frontend}}} (we just saw in [wiki:Tutorial4AddInputFrontend previous tutorial] how to create such {{{Frontend}}}s). This methods takes as first argument the {{{Frontend}}} path in '''{{{/dev}}}'''. An additional argument can be given to override the {{{DEFAULT_AXIS_CALIBRATION}}} table. 14 15 {{{ 16 #!python 11 17 12 18 def _buildComponents(self): … … 50 56 }}} 51 57 52 The first method, {{{_createFrontend()}}} must return a valid frontend (we just saw in [wiki:Tutorial4AddInputFrontend previous tutorial] how to create such frontends). This methods takes as first argument the frontend path in '''{{{/dev}}}'''. An additional argument can be given to override the {{{DEFAULT_AXIS_CALIBRATION}}} table.58 Interesting things take place in {{{_buildComponents()}}}: this is where {{{Component}}}s ({{{Button}}}, {{{Analog}}}...) of our remote control are created. 53 59 54 In the second method, {{{_buildComponents()}}}, interesting things take place: this is where {{{Component}}}s ({{{Button}}}, {{{Analog}}}...) of our remote control are created.60 We first define 2 remote control configs, '''walk''' and '''body''', as we don't have enough buttons to do all we want. In the first config, '''walk''', we define some components to make the robot walk, but also to change the body position (by increments). In the second config, '''body''', we define additional components to control the body. If no '''config''' is specified in the {{{Component}}} definition, it means it is available in all configs. 55 61 56 We first define 2 remote control configs, ''walk'' and ''body'', as we don't have enough buttons to do all we want. In the first config, ''walk'', we define some components to make the robot walk, but also to change the body position (by increments). Note that when the config is not specified in the component definition, it means it is available in all configs. In the second config, ''body'', we define additional components to control the body.62 Then we add the components, using the {{{_addComponent()}}} method helper. See [wiki:UserGuideGit#Remotecontrols user guide] for complete description. 57 63 58 Then we add the components, using the {{{_addComponent()}}} method helper. This method takes the component class, the command to execute, the frontend key, a optional modifier, and a mapper.64 But let's see how things really work. 59 65 60 Blah 66 {{{RemoteControl}}} is a thread, running a infinite main loop. During an iteration, each {{{Component}}} is checked. If triggered, the {{{Component}}} sends its output to the {{{Mapper}}}, which in turn sends its output to the '''command''' callable. 61 67 62 {{{Mapper}}}s are simple objects helping to adapt params from {{{RemoteControl}}} {{{Component}}}s output to {{{Robot}}}/{{{GaitSequencer}}} methods input.68 For {{{Button}}}, triggering depends on the optional '''trigger''' param. For {{{Switch}}}, triggering occurs when the state toggles. For {{{Analog}}}, triggering occurs when the value changes. For {{{Joystick}}}, triggering occurs when any value changes. If a '''modifier''' is specified, it must be pressed for the triggering to occur. It acts as a keyboard shift or control key. This way, the main key can be used in different {{{Component}}}s. 63 69 64 For example, to control the robot walk, we can create a {{{Joystick}}} component with 3 axes: X, Y, RZ.70 Ok, now let's dig a little bit into the {{{Mapper}}}s. 65 71 66 But the {{{GaitSequencer}}} {{{walk()}}} method expects '''speed''', '''direction''', '''length''' and '''angle''' params. Using the {{{MapperWalk}}} mapper, you can compute all these params from X/Y/RZ axes, and send them to the {{{walk()}}} method. That's what we did in the [wiki:Tutorial1FirstRobot tutorial 1].72 To control the robot walk, we created a {{{Joystick}}} {{{Component}}} with 3 axes, X, Y and RZ. These 3 values will be send as a tuple as soon as one of them changes. 67 73 68 See [https://framagit.org/fma38/Py4bot/blob/master/py4bot/inputs/mappers/mapper.py py4bot/inputs/mappers/mapper.py] to see how this mapper is defined.74 But the {{{GaitSequencer}}} {{{walk()}}} method expects '''speed''', '''direction''', '''length''' and '''angle''' params. We used the {{{MapperWalk}}} mapper, which computes all these params from X/Y/RZ values, which can be sent to the {{{walk()}}} method. 69 75 70 Of course, wa can define our own {{{Mappers}}}.76 See [https://framagit.org/fma38/Py4bot/blob/master/py4bot/inputs/mappers/mapper.py py4bot/inputs/mappers/mapper.py] to see how mappers are defined. 71 77 72 78 Of course, we can define our own {{{Mappers}}}; they don't need to be in the {{{mapper.py}}} file, we can put them in our own code.
