Formas de se fazer um seguidor de linha no lego mindstorms 51515
- Eduardo Brennand Paranhos
- 1 de dez. de 2024
- 3 min de leitura
Neste post, iremos nos aprofundar em duas maneiras as quais podemos utilizar para fazer um seguidor de linha no lego mindstorms robot inventor(51515).
A primeira delas trata-se da mais convencional, utilizar as leituras do sensor de cor que vem no kit para fazer seu robô seguir a linha. Embora seja um meio bastante simples e rápido de fazer um seguidor de linha, ele apresenta algumas desvantagens, como o fato de não ser tão rápido ou eficiente, por exemplo.
Código utilizado para esse modelo:

Demonstração do modelo:
A outra forma de construir um seguidor de linha nesta plataforma é utilizando a câmera huskylens, da Dfrobot. Trata-se de uma câmera bastante fácil de se programar, mas ainda requer alguns conhecimentos a mais, em relação ao modelo anterior. Ela é bem mais precisa e funciona de forma mais suave, mas requer uma fonte externa para utilizá-la.
Para utilizá-la, instale a biblioteca pyhuskylens.py no python do app lego:
import ubinascii, uos, machine,uhashlib
from ubinascii import hexlify
b64="""TQUCHyCLCOgQTgAHLExpYnJhcnkvcHlodXNreWxlbnMucHk5KDA5UGUlRYAdHx8fK2YkJCQkJCQkJEQkJGQgixSLEoupAIAQEHNsZWVwX21zEBB0aWNrc19tcyoCGwh0aW1lHAUWARwFFgFZgFEbDHN0cnVjdBYBgBAASCoBGwBzHABIFgBIWYAQCmF0YW4yEA5kZWdyZWVzKgIbCG1hdGgcBRYBHAUWAVmAEAhwb3J0KgEbBmh1YhwDFgFZMgIWCGJ5dGUjABYMSEVBREVSIwEWDEZBSUxFRDIDEQB8oCI+NAI0ATAeFg5SRVFVRVNUFhxSRVFVRVNUX0JMT0NLUxYcUkVRVUVTVF9BUlJPV1MWHlJFUVVFU1RfTEVBUk5FRBYsUkVRVUVTVF9CTE9DS1NfTEVBUk5FRBYsUkVRVUVTVF9BUlJPV1NfTEVBUk5FRBYaUkVRVUVTVF9CWV9JRBYoUkVRVUVTVF9CTE9DS1NfQllfSUQWKFJFUVVFU1RfQVJST1dTX0JZX0lEFhZSRVRVUk5fSU5GTxYYUkVUVVJOX0JMT0NLFhhSRVRVUk5fQVJST1cWGlJFUVVFU1RfS05PQ0sWIlJFUVVFU1RfQUxHT1JJVEhNFhJSRVRVUk5fT0sWJlJFUVVFU1RfQ1VTVE9NTkFNRVMWGlJFUVVFU1RfUEhPVE8WJFJFUVVFU1RfU0VORF9QSE9UTxYuUkVRVUVTVF9TRU5EX0tOT1dMRURHRVMWNFJFUVVFU1RfUkVDRUlWRV9LTk9XTEVER0VTFiZSRVFVRVNUX0NVU1RPTV9URVhUFiRSRVFVRVNUX0NMRUFSX1RFWFQWGlJFUVVFU1RfTEVBUk4WHFJFUVVFU1RfRk9SR0VUFi5SRVFVRVNUX1NFTkRfU0NSRUVOU0hPVBYuUkVRVUVTVF9TQVZFX1NDUkVFTlNIT1QWPFJFUVVFU1RfTE9BRF9BSV9GUkFNRV9GUk9NX1VTQhYcUkVRVUVTVF9JU19QUk8WMFJFUVVFU1RfRklSTVdBUkVfVkVSU0lPThYWUkVUVVJOX0JVU1kRBRYaUkVUVVJOX0lTX1BST4AWNEFMR09SSVRITV9GQUNFX1JFQ09HTklUSU9OgRYyQUxHT1JJVEhNX09CSkVDVF9UUkFDS0lOR4IWOEFMR09SSVRITV9PQkpFQ1RfUkVDT0dO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
"""
def calc_hash(b):
return hexlify(uhashlib.sha256(b).digest()).decode()
# this is the hash of the compiled mpy
hash_gen='3af861ba999a2843b8873036adb9cbca23d288a637a3cec237b68da3cddd34b0'
pyhuskylens=ubinascii.a2b_base64(b64)
hash_initial=calc_hash(pyhuskylens)
try: # remove any old versions of pyhuskylens library
uos.remove('/projects/pyhuskylens.py')
uos.remove('/projects/pyhuskylens.mpy')
except OSError:
pass
print('writing pyhuskylens.mpy to folder /projects')
with open('/projects/pyhuskylens.mpy','wb') as f:
f.write(pyhuskylens)
print('Finished writing pyhuskylens.mpy.')
print('Checking hash.')
pyhuskylens_check=open('/projects/pyhuskylens.mpy','rb').read()
hash_check=calc_hash(pyhuskylens_check)
print('Hash generated: ',hash_gen)
error=False
if hash_initial != hash_gen:
print('Failed hash of base64 input : '+hash_initial)
error=True
if hash_check != hash_gen:
print('Failed hash of .mpy on SPIKE: '+hash_check)
error=True
if not error:
print('pyhuskylens library written succesfully. Resetting....')
machine.reset()
else:
print('Failure in pyhuskylens library!')
feito isso, apague este programa e rode o código do seguidor de linha:
from mindstorms import MSHub, Motor, MotorPair, ColorSensor, DistanceSensor, App
from mindstorms.control import wait_for_seconds, wait_until, Timer
from mindstorms.operator import greater_than, greater_than_or_equal_to, less_than, less_than_or_equal_to, equal_to, not_equal_to
import math
from projects.pyhuskylens import (HuskyLens,
ALGORITHM_FACE_RECOGNITION,
ALGORITHM_FACE_RECOGNITION,
ALGORITHM_OBJECT_TRACKING,
ALGORITHM_OBJECT_RECOGNITION,
ALGORITHM_LINE_TRACKING,
ALGORITHM_COLOR_RECOGNITION,
ALGORITHM_TAG_RECOGNITION,
ALGORITHM_OBJECT_CLASSIFICATION,
ALGORITHM_QR_CODE_RECOGNITION,
ALGORITHM_BARCODE_RECOGNITION,
ARROWS, # key for get() dict
BLOCKS, # key for get() dict
FRAME, # key for get() dict
clamp_int)
### huskylens usage ###
# get_blocks(ID=None, learned=False) returns a list of block objects
# blocks have x, y , width , height, ID properties.
# get_arrows(ID=None, learned=False) returns a list of arrow objects
# arrows have x_tail, y_tail , x_head , y_head, ID and direction properties
# get(ID=None, learned=False) returns a dict with blocks, arrows & frame
# on firmware 0.5+ you also have these class methods available:
# show_text("text", position=(10,10))
# clear_text()
# Create your objects here.
ms_hub = MSHub()
hl = HuskyLens('B', baud=9600)
ma = Motor('D')
mb = Motor('A')
# Write your program here.
ms_hub.speaker.beep()
# Get direction of a learned arrow
print("Starting line tracking")
hl.set_alg(ALGORITHM_LINE_TRACKING)
while not ms_hub.left_button.is_pressed():
arrows = hl.get_arrows(learned=False)
if len(arrows) > 0:
direction = ((arrows[0].x_head+arrows[0].x_tail)/2 - 160)/-6
ma.start_at_power(clamp_int(30+direction))
mb.start_at_power(clamp_int(-30+direction))
else:
ma.start_at_power(0)
mb.start_at_power(0)
ma.start_at_power(0)
mb.start_at_power(0)
Vídeo demonstrando o modelo:
Agora que mostramos as diferentes formas de se fazer um seguidor de linha com o lego mindstorms, cabe a você escolher qual utilizar em seus projetos!
Comments