Проблема:
У меня есть базовый класс робота (gopigo3), который реализует низкоуровневые методы робота.
У меня также есть класс, наследующий базовый робот класс (easygopigo3), который позволяет использовать методы низкого уровня без всех суетливых деталей.
Я написал базовую программу на Python (test_servos), которая перемещает сервоприводы вокруг перемещения робота по панорамированию и наклону из стороны в сторону, вверх и вниз.
Соответствующая часть класса GoPiGo3 (базовый класс) выглядит следующим образом:
Соответствующая часть класса GoPiGo3 (базовый класс) выглядит следующим образом:
р>
# https://www.dexterindustries.com/GoPiGo/
# https://github.com/DexterInd/GoPiGo3
#
# Copyright (c) 2017 Dexter Industries
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GoPiGo3/blob/master/LICENSE.md
#
# Python drivers for the GoPiGo3
from __future__ import print_function
from __future__ import division
#from builtins import input
hardware_connected = True
__version__ = "1.3.2"
import subprocess # for executing system calls
try:
import spidev
import fcntl # for lockf mutex support
except:
hardware_connected = False
print ("Can't import spidev or fcntl")
import math # import math for math.pi constant
import time
import json
FIRMWARE_VERSION_REQUIRED = "1.0.x" # Make sure the top 2 of 3 numbers match
import pigpio
if hardware_connected:
GPG_SPI = spidev.SpiDev()
GPG_SPI.open(0, 1)
GPG_SPI.max_speed_hz = 500000
GPG_SPI.mode = 0b00
GPG_SPI.bits_per_word = 8
class GoPiGo3(object):
WHEEL_BASE_WIDTH = 117 # distance (mm) from left wheel to right wheel. This works with the initial GPG3 prototype. Will need to be adjusted.
WHEEL_DIAMETER = 66.5 # wheel diameter (mm)
WHEEL_BASE_CIRCUMFERENCE = WHEEL_BASE_WIDTH * math.pi # The circumference of the circle the wheels will trace while turning (mm)
WHEEL_CIRCUMFERENCE = WHEEL_DIAMETER * math.pi # The circumference of the wheels (mm)
MOTOR_GEAR_RATIO = 120 # Motor gear ratio # 220 for Nicole's prototype
ENCODER_TICKS_PER_ROTATION = 6 # Encoder ticks per motor rotation (number of magnet positions) # 16 for early prototypes
MOTOR_TICKS_PER_DEGREE = ((MOTOR_GEAR_RATIO * ENCODER_TICKS_PER_ROTATION) / 360.0) # encoder ticks per output shaft rotation degree
GROVE_I2C_LENGTH_LIMIT = 32
SPI_MESSAGE_TYPE = Enumeration("""
NONE,
GET_MANUFACTURER,
GET_NAME,
GET_HARDWARE_VERSION,
GET_FIRMWARE_VERSION,
GET_ID,
SET_LED,
GET_VOLTAGE_5V,
GET_VOLTAGE_VCC,
SET_SERVO,
SET_MOTOR_PWM,
SET_MOTOR_POSITION,
SET_MOTOR_POSITION_KP,
SET_MOTOR_POSITION_KD,
SET_MOTOR_DPS,
SET_MOTOR_LIMITS,
OFFSET_MOTOR_ENCODER,
GET_MOTOR_ENCODER_LEFT,
GET_MOTOR_ENCODER_RIGHT,
GET_MOTOR_STATUS_LEFT,
GET_MOTOR_STATUS_RIGHT,
SET_GROVE_TYPE,
SET_GROVE_MODE,
SET_GROVE_STATE,
SET_GROVE_PWM_DUTY,
SET_GROVE_PWM_FREQUENCY,
GET_GROVE_VALUE_1,
GET_GROVE_VALUE_2,
GET_GROVE_STATE_1_1,
GET_GROVE_STATE_1_2,
GET_GROVE_STATE_2_1,
GET_GROVE_STATE_2_2,
GET_GROVE_VOLTAGE_1_1,
GET_GROVE_VOLTAGE_1_2,
GET_GROVE_VOLTAGE_2_1,
GET_GROVE_VOLTAGE_2_2,
GET_GROVE_ANALOG_1_1,
GET_GROVE_ANALOG_1_2,
GET_GROVE_ANALOG_2_1,
GET_GROVE_ANALOG_2_2,
START_GROVE_I2C_1,
START_GROVE_I2C_2,
""")
GROVE_TYPE = Enumeration("""
CUSTOM = 1,
IR_DI_REMOTE,
IR_EV3_REMOTE,
US,
I2C,
""")
GROVE_STATE = Enumeration("""
VALID_DATA,
NOT_CONFIGURED,
CONFIGURING,
NO_DATA,
I2C_ERROR,
""")
LED_EYE_LEFT = 0x02
LED_EYE_RIGHT = 0x01
LED_BLINKER_LEFT = 0x04
LED_BLINKER_RIGHT = 0x08
LED_LEFT_EYE = LED_EYE_LEFT
LED_RIGHT_EYE = LED_EYE_RIGHT
LED_LEFT_BLINKER = LED_BLINKER_LEFT
LED_RIGHT_BLINKER = LED_BLINKER_RIGHT
LED_WIFI = 0x80 # Used to indicate WiFi status. Should not be controlled by the user.
SERVO_1 = 0x01
SERVO_2 = 0x02
MOTOR_LEFT = 0x01
MOTOR_RIGHT = 0x02
MOTOR_FLOAT = -128
GROVE_1_1 = 0x01
GROVE_1_2 = 0x02
GROVE_2_1 = 0x04
GROVE_2_2 = 0x08
GROVE_1 = GROVE_1_1 + GROVE_1_2
GROVE_2 = GROVE_2_1 + GROVE_2_2
GroveType = [0, 0]
GroveI2CInBytes = [0, 0]
GROVE_INPUT_DIGITAL = 0
GROVE_OUTPUT_DIGITAL = 1
GROVE_INPUT_DIGITAL_PULLUP = 2
GROVE_INPUT_DIGITAL_PULLDOWN = 3
GROVE_INPUT_ANALOG = 4
GROVE_OUTPUT_PWM = 5
GROVE_INPUT_ANALOG_PULLUP = 6
GROVE_INPUT_ANALOG_PULLDOWN = 7
GROVE_LOW = 0
GROVE_HIGH = 1
def __init__(self, addr = 8, detect = True, config_file_path="/home/pi/Dexter/gpg3_config.json"):
"""
Do any necessary configuration, and optionally detect the GoPiGo3
* Optionally set the SPI address to something other than 8
* Optionally disable the detection of the GoPiGo3 hardware. This can be used for debugging
and testing when the GoPiGo3 would otherwise not pass the detection tests.
The ``config_file_path`` parameter represents the path to a JSON file. The presence of this configuration file is optional and is only required in cases where
the GoPiGo3 has a skewed trajectory due to minor differences in these two constants: the **wheel diameter** and the **wheel base width**. In most cases, this won't be the case.
By-default, the constructor tries to read the ``config_file_path`` file and silently fails if something goes wrong: wrong permissions, non-existent file, improper key values and so on.
To set custom values to these 2 constants, use :py:meth:`~easygopigo3.EasyGoPiGo3.set_robot_constants` method and for saving the constants to a file call
:py:meth:`~easygopigo3.EasyGoPiGo3.save_robot_constants` method.
"""
# Make sure the SPI lines are configured for mode ALT0 so that the hardware SPI controller can use them
# subprocess.call('gpio mode 12 ALT0', shell=True)
# subprocess.call('gpio mode 13 ALT0', shell=True)
# subprocess.call('gpio mode 14 ALT0', shell=True)
pi_gpio = pigpio.pi()
pi_gpio.set_mode(9, pigpio.ALT0)
pi_gpio.set_mode(10, pigpio.ALT0)
pi_gpio.set_mode(11, pigpio.ALT0)
pi_gpio.stop()
self.SPI_Address = addr
if detect == True:
try:
manufacturer = self.get_manufacturer()
board = self.get_board()
vfw = self.get_version_firmware()
except IOError:
raise IOError("No SPI response. GoPiGo3 with address %d not connected." % addr)
if manufacturer != "Dexter Industries" or board != "GoPiGo3":
raise IOError("GoPiGo3 with address %d not connected." % addr)
if vfw.split('.')[0] != FIRMWARE_VERSION_REQUIRED.split('.')[0] or \
vfw.split('.')[1] != FIRMWARE_VERSION_REQUIRED.split('.')[1]:
raise FirmwareVersionError("GoPiGo3 firmware needs to be version %s but is currently version %s" \
% (FIRMWARE_VERSION_REQUIRED, vfw))
# load wheel diameter & wheel base width
# also default ENCODER_TICKS_PER_ROTATION and MOTOR_GEAR_RATIO
# should there be a problem doing that then save the current default configuration
try:
self.load_robot_constants(config_file_path)
except Exception as e:
pass
def get_id(self):
"""
Read the 128-bit GoPiGo3 hardware serial number
Returns touple:
serial number as 32 char HEX formatted string, error
"""
outArray = [self.SPI_Address, self.SPI_MESSAGE_TYPE.GET_ID,\
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
reply = self.spi_transfer_array(outArray)
if(reply[3] == 0xA5):
return ("%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" % \
(reply[4], reply[5], reply[6], reply[7], reply[8], reply[9], reply[10], reply[11], \
reply[12], reply[13], reply[14], reply[15], reply[16], reply[17], reply[18], reply[19]))
raise IOError("No SPI response")
return "00000000000000000000000000000000"
Соответствующая часть класса easygopigo3 (наследующий класс) выглядит следующим образом:
#!/usr/bin/env python3
from __future__ import print_function
from __future__ import division
# from builtins import input
import sys
# import tty
# import select
import time
import os
import math
import json
import easysensors
from I2C_mutex import Mutex
__version__ = "1.3.2.1"
try:
from di_sensors import easy_line_follower, easy_distance_sensor, easy_light_color_sensor, easy_inertial_measurement_unit
di_sensors_available = True
except ImportError as err:
di_sensors_available = False
print("Importing di_sensors error: {}".format(err))
except Exception as err:
di_sensors_available = False
print("Importing di_sensors error: {}".format(err))
mutex = Mutex(debug=False)
hardware_connected = True
try:
import gopigo3
except ImportError:
hardware_connected = False
print("Cannot import gopigo3 library")
except Exception as e:
hardware_connected = False
print("Unknown issue while importing gopigo3")
print(e)
# try:
# from line_follower import line_sensor
# from line_follower import scratch_line
# # is_line_follower_accessible not really used, just in case
# is_line_follower_accessible = True
# except:
# try:
# sys.path.insert(0, '/home/pi/GoPiGo/Software/Python/line_follower')
# import line_sensor
# import scratch_line
# is_line_follower_accessible = True
# except:
# is_line_follower_accessible = False
##########################
def debug(in_str):
if False:
print(in_str)
#####################################################################
#
# EASYGOPIGO3
#
#####################################################################
class EasyGoPiGo3(gopigo3.GoPiGo3):
"""
This class is used for controlling a `GoPiGo3`_ robot.
With this class you can do the following things with your `GoPiGo3`_:
* Drive your robot in any number of directions.
* Have precise control over the direction of the robot.
* Set the speed of the robot.
* Turn *on* or *off* the blinker LEDs.
* Control the `GoPiGo3`_' Dex's *eyes*, *color* and so on ...
.. needs revisiting
.. warning::
Without a battery pack connected to the `GoPiGo3`_, the robot won't move.
"""
def __init__(self, config_file_path="/home/pi/Dexter/gpg3_config.json", use_mutex=False):
"""
This constructor sets the variables to the following values:
:param str config_file_path = "/home/pi/Dexter/gpg3_config.json": Path to JSON config file that stores the wheel diameter and wheel base width for the GoPiGo3.
:param boolean use_mutex = False: When using multiple threads/processes that access the same resource/device, mutex has to be enabled.
:var int speed = 300: The speed of the motors should go between **0-1000** DPS.
:var tuple(int,int,int) left_eye_color = (0,255,255): Set Dex's left eye color to **turqoise**.
:var tuple(int,int,int) right_eye_color = (0,255,255): Set Dex's right eye color to **turqoise**.
:var int DEFAULT_SPEED = 300: Starting speed value: not too fast, not too slow.
:raises IOError: When the GoPiGo3 is not detected. It also debugs a message in the terminal.
:raises gopigo3.FirmwareVersionError: If the GoPiGo3 firmware needs to be updated. It also debugs a message in the terminal.
:raises Exception: For any other kind of exceptions.
"""
try:
if sys.version_info[0] < 3:
super(self.__class__, self).__init__(config_file_path=config_file_path)
else:
super().__init__(config_file_path=config_file_path)
except IOError as e:
print("FATAL ERROR:\nGoPiGo3 is not detected.")
raise e
except gopigo3.FirmwareVersionError as e:
print("FATAL ERROR:\nTo update the firmware on Raspbian for Robots you need to run DI Software Update and choose Update Robot")
raise e
except Exception as e:
raise e
self.sensor_1 = None
self.sensor_2 = None
self.DEFAULT_SPEED = 300
self.NO_LIMIT_SPEED = 1000
self.set_speed(self.DEFAULT_SPEED)
self.left_eye_color = (0, 255, 255)
self.right_eye_color = (0, 255, 255)
self.use_mutex = use_mutex
Моя процедура «test_servos» хочет использовать индивидуальный серийный номер для каждого робота, чтобы установить соответствующие константы центрирования сервопривода, поскольку они разные. Однако метод, который получает серийный номер робота, является методом базового класса (gopigo3), а не наследующего класса (easygopigo3).
Моя процедура test_servos выглядит так:
#!/usr/bin/python3.7
import easygopigo3 as easy
import time
import gopigo3 # import the GoPiGo3 drivers
# Instantiate native GoPiGo libraries
difficult_gpg = gopigo3.GoPiGo3() # Create an instance of the GoPiGo3 class. GPG will be the GoPiGo3 object.
serial_number = difficult_gpg.get_id() # read and display the serial number
# Instantiate easy GoPiGo libraries
easy_gpg = easy.EasyGoPiGo3()
servo_1 = easy_gpg.init_servo('SERVO1')
servo_2 = easy_gpg.init_servo('SERVO2')
sleep_time = 0.50 # pause time in seconds
#Servo constants
if serial_number == "A0F6E45F4E514B4B41202020FF152B11":
# Charlene's servo constants
print("Serial number is", serial_number)
print("Robot is \"Charlene\"")
center_1 = 86
center_2 = 80
right = center_1 - 45
left = center_1 + 45
up = center_2 - 45
down = center_2 + 45
elif serial_number == "A0F6E45F4E514B4B41202020FF152B12":
# Charlie's servo constants
center_1 = 86
center_2 = 80
right = center_1 - 45
left = center_1 + 45
up = center_2 - 45
down = center_2 + 45
else:
print("I don't know who robot", serial_number, "is.")
print("(or if it's even a robot) Aborting!")
quit()
# start
print("Center Both Servos")
servo_1.rotate_servo(center_1)
servo_2.rotate_servo(center_2)
time.sleep(sleep_time)
print("Test Servo 1")
servo_1.rotate_servo(right)
time.sleep(sleep_time)
servo_1.rotate_servo(left)
time.sleep(sleep_time)
servo_1.rotate_servo(center_1)
time.sleep(sleep_time)
print("Test Servo 2")
servo_2.rotate_servo(up)
time.sleep(sleep_time)
servo_2.rotate_servo(down)
time.sleep(sleep_time)
print("Re-Center Both Servos")
servo_1.rotate_servo(center_1)
servo_2.rotate_servo(center_2)
time.sleep(sleep_time)
servo_1.disable_servo()
servo_2.disable_servo()
В приведенном выше коде вы заметите, что я создаю экземпляры обоих классов, чтобы иметь возможность использовать методы базового класса. Однако «дзен» кода «Pythonic» указывает на то, что я должен быть как можно ленивее и использовать минимум кода, необходимый для выполнения работы. Мне кажется, что я должен иметь возможность использовать методы базового класса изнутри наследующего класса, не создавая отдельный экземпляр.
Учитывая всю эту информацию, как мне использовать базовый класс? ' методы в экземпляре моего кода наследующего класса?
Проблема: У меня есть базовый класс робота (gopigo3), который реализует низкоуровневые методы робота. У меня также есть класс, наследующий базовый робот класс (easygopigo3), который позволяет использовать методы низкого уровня без всех суетливых деталей. Я написал базовую программу на Python (test_servos), которая перемещает сервоприводы вокруг перемещения робота по панорамированию и наклону из стороны в сторону, вверх и вниз. Соответствующая часть класса GoPiGo3 (базовый класс) выглядит следующим образом: Соответствующая часть класса GoPiGo3 (базовый класс) выглядит следующим образом: р> [code]# https://www.dexterindustries.com/GoPiGo/ # https://github.com/DexterInd/GoPiGo3 # # Copyright (c) 2017 Dexter Industries # Released under the MIT license (http://choosealicense.com/licenses/mit/). # For more information see https://github.com/DexterInd/GoPiGo3/blob/master/LICENSE.md # # Python drivers for the GoPiGo3
from __future__ import print_function from __future__ import division #from builtins import input hardware_connected = True __version__ = "1.3.2"
import subprocess # for executing system calls try: import spidev import fcntl # for lockf mutex support except: hardware_connected = False print ("Can't import spidev or fcntl")
import math # import math for math.pi constant import time import json
FIRMWARE_VERSION_REQUIRED = "1.0.x" # Make sure the top 2 of 3 numbers match
class GoPiGo3(object): WHEEL_BASE_WIDTH = 117 # distance (mm) from left wheel to right wheel. This works with the initial GPG3 prototype. Will need to be adjusted. WHEEL_DIAMETER = 66.5 # wheel diameter (mm) WHEEL_BASE_CIRCUMFERENCE = WHEEL_BASE_WIDTH * math.pi # The circumference of the circle the wheels will trace while turning (mm) WHEEL_CIRCUMFERENCE = WHEEL_DIAMETER * math.pi # The circumference of the wheels (mm)
MOTOR_GEAR_RATIO = 120 # Motor gear ratio # 220 for Nicole's prototype ENCODER_TICKS_PER_ROTATION = 6 # Encoder ticks per motor rotation (number of magnet positions) # 16 for early prototypes MOTOR_TICKS_PER_DEGREE = ((MOTOR_GEAR_RATIO * ENCODER_TICKS_PER_ROTATION) / 360.0) # encoder ticks per output shaft rotation degree
def __init__(self, addr = 8, detect = True, config_file_path="/home/pi/Dexter/gpg3_config.json"): """ Do any necessary configuration, and optionally detect the GoPiGo3
* Optionally set the SPI address to something other than 8 * Optionally disable the detection of the GoPiGo3 hardware. This can be used for debugging and testing when the GoPiGo3 would otherwise not pass the detection tests.
The ``config_file_path`` parameter represents the path to a JSON file. The presence of this configuration file is optional and is only required in cases where the GoPiGo3 has a skewed trajectory due to minor differences in these two constants: the **wheel diameter** and the **wheel base width**. In most cases, this won't be the case.
By-default, the constructor tries to read the ``config_file_path`` file and silently fails if something goes wrong: wrong permissions, non-existent file, improper key values and so on. To set custom values to these 2 constants, use :py:meth:`~easygopigo3.EasyGoPiGo3.set_robot_constants` method and for saving the constants to a file call :py:meth:`~easygopigo3.EasyGoPiGo3.save_robot_constants` method.
"""
# Make sure the SPI lines are configured for mode ALT0 so that the hardware SPI controller can use them # subprocess.call('gpio mode 12 ALT0', shell=True) # subprocess.call('gpio mode 13 ALT0', shell=True) # subprocess.call('gpio mode 14 ALT0', shell=True)
self.SPI_Address = addr if detect == True: try: manufacturer = self.get_manufacturer() board = self.get_board() vfw = self.get_version_firmware() except IOError: raise IOError("No SPI response. GoPiGo3 with address %d not connected." % addr) if manufacturer != "Dexter Industries" or board != "GoPiGo3": raise IOError("GoPiGo3 with address %d not connected." % addr) if vfw.split('.')[0] != FIRMWARE_VERSION_REQUIRED.split('.')[0] or \ vfw.split('.')[1] != FIRMWARE_VERSION_REQUIRED.split('.')[1]: raise FirmwareVersionError("GoPiGo3 firmware needs to be version %s but is currently version %s" \ % (FIRMWARE_VERSION_REQUIRED, vfw))
# load wheel diameter & wheel base width # also default ENCODER_TICKS_PER_ROTATION and MOTOR_GEAR_RATIO # should there be a problem doing that then save the current default configuration try: self.load_robot_constants(config_file_path) except Exception as e: pass
def get_id(self): """ Read the 128-bit GoPiGo3 hardware serial number
Returns touple: serial number as 32 char HEX formatted string, error """ outArray = [self.SPI_Address, self.SPI_MESSAGE_TYPE.GET_ID,\ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] reply = self.spi_transfer_array(outArray) if(reply[3] == 0xA5): return ("%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" % \ (reply[4], reply[5], reply[6], reply[7], reply[8], reply[9], reply[10], reply[11], \ reply[12], reply[13], reply[14], reply[15], reply[16], reply[17], reply[18], reply[19])) raise IOError("No SPI response") return "00000000000000000000000000000000" [/code] Соответствующая часть класса easygopigo3 (наследующий класс) выглядит следующим образом: [code]#!/usr/bin/env python3 from __future__ import print_function from __future__ import division # from builtins import input
import sys # import tty # import select import time import os import math import json import easysensors from I2C_mutex import Mutex
class EasyGoPiGo3(gopigo3.GoPiGo3): """ This class is used for controlling a `GoPiGo3`_ robot.
With this class you can do the following things with your `GoPiGo3`_:
* Drive your robot in any number of directions. * Have precise control over the direction of the robot. * Set the speed of the robot. * Turn *on* or *off* the blinker LEDs. * Control the `GoPiGo3`_' Dex's *eyes*, *color* and so on ...
.. needs revisiting
.. warning::
Without a battery pack connected to the `GoPiGo3`_, the robot won't move.
"""
def __init__(self, config_file_path="/home/pi/Dexter/gpg3_config.json", use_mutex=False): """ This constructor sets the variables to the following values:
:param str config_file_path = "/home/pi/Dexter/gpg3_config.json": Path to JSON config file that stores the wheel diameter and wheel base width for the GoPiGo3. :param boolean use_mutex = False: When using multiple threads/processes that access the same resource/device, mutex has to be enabled. :var int speed = 300: The speed of the motors should go between **0-1000** DPS. :var tuple(int,int,int) left_eye_color = (0,255,255): Set Dex's left eye color to **turqoise**. :var tuple(int,int,int) right_eye_color = (0,255,255): Set Dex's right eye color to **turqoise**. :var int DEFAULT_SPEED = 300: Starting speed value: not too fast, not too slow. :raises IOError: When the GoPiGo3 is not detected. It also debugs a message in the terminal. :raises gopigo3.FirmwareVersionError: If the GoPiGo3 firmware needs to be updated. It also debugs a message in the terminal. :raises Exception: For any other kind of exceptions.
""" try: if sys.version_info[0] < 3: super(self.__class__, self).__init__(config_file_path=config_file_path) else: super().__init__(config_file_path=config_file_path) except IOError as e: print("FATAL ERROR:\nGoPiGo3 is not detected.") raise e except gopigo3.FirmwareVersionError as e: print("FATAL ERROR:\nTo update the firmware on Raspbian for Robots you need to run DI Software Update and choose Update Robot") raise e except Exception as e: raise e
self.sensor_1 = None self.sensor_2 = None self.DEFAULT_SPEED = 300 self.NO_LIMIT_SPEED = 1000 self.set_speed(self.DEFAULT_SPEED) self.left_eye_color = (0, 255, 255) self.right_eye_color = (0, 255, 255) self.use_mutex = use_mutex [/code] Моя процедура «test_servos» хочет использовать индивидуальный серийный номер для каждого робота, чтобы установить соответствующие константы центрирования сервопривода, поскольку они разные. Однако метод, который получает серийный номер робота, является методом [b]базового класса[/b] (gopigo3), а не [b]наследующего класса[/b] (easygopigo3). Моя процедура test_servos выглядит так: [code]#!/usr/bin/python3.7
import easygopigo3 as easy import time import gopigo3 # import the GoPiGo3 drivers
# Instantiate native GoPiGo libraries difficult_gpg = gopigo3.GoPiGo3() # Create an instance of the GoPiGo3 class. GPG will be the GoPiGo3 object.
serial_number = difficult_gpg.get_id() # read and display the serial number
print("Re-Center Both Servos") servo_1.rotate_servo(center_1) servo_2.rotate_servo(center_2) time.sleep(sleep_time) servo_1.disable_servo() servo_2.disable_servo() [/code] В приведенном выше коде вы заметите, что я создаю экземпляры обоих классов, чтобы иметь возможность использовать методы базового класса. Однако «дзен» кода «Pythonic» указывает на то, что я должен быть как можно ленивее и использовать минимум кода, необходимый для выполнения работы. Мне кажется, что я должен иметь возможность использовать методы базового класса изнутри наследующего класса, не создавая отдельный экземпляр. Учитывая всю эту информацию, как мне использовать базовый класс? ' методы в экземпляре моего кода наследующего класса?
Проблема:
У меня есть базовый класс робота (gopigo3), который реализует низкоуровневые функциональные и коммуникационные методы робота.
У меня также есть класс, который наследует базовый класс робота (easygopigo3), который предоставляет возможность...
Дано:
Класс «А» ( class_a ), в котором есть все низкоуровневые процедуры, которые мой робот использует для выполнения своих задач.
class_a включает метод get_sn, который возвращает уникальный серийный номер этого робота.
Класс B , ( class_b )...
Я создаю дочерний объект на основе родительского объекта. Итак, сценарий таков, что у меня есть объект и дочерний объект, который добавляет свойство расстояния для сценариев, в которых я хочу выполнять поиск. Я решил использовать наследование,...
Я создаю библиотеку и хочу, чтобы пользователь мог создать ее экземпляр следующим образом:
int main (int, char**)
{
Child_Type1 c1 = Child_Type1();
Child_Type2 c2 = Child_Type2();
// ...
}
Базовый класс определяется тремя аргументами шаблона и...