Skip to content

Instantly share code, notes, and snippets.

@mestcihazal
Last active February 7, 2023 23:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mestcihazal/e78e3b29c58aa301c9a197ada272e6a0 to your computer and use it in GitHub Desktop.
Save mestcihazal/e78e3b29c58aa301c9a197ada272e6a0 to your computer and use it in GitHub Desktop.
Scuttle code for following a red object
import asyncio
from viam.robot.client import RobotClient
from viam.rpc.dial import Credentials, DialOptions
from viam.services.vision import VisionServiceClient
from viam.services.vision import VisModelConfig, VisModelType, Detection
from viam.components.camera import Camera
from viam.components.base import Base
async def connect():
creds = Credentials(
type='robot-location-secret',
payload='[PLEASE ADD YOUR SECRET HERE. YOU CAN FIND THIS ON THE CODE SAMPLE TAB]')
opts = RobotClient.Options(
refresh_interval=0,
dial_options=DialOptions(credentials=creds)
)
return await RobotClient.at_address('[ADD YOUR ROBOT ADDRESS HERE. YOU CAN FIND THIS ON THE CODE SAMPLE TAB]', opts)
# Get largest detection box and see if it's center is in the left, center, or right third
def leftOrRight(detections, midpoint):
largest_area = 0
largest = Detection()
if not detections:
print("nothing detected :(")
return -1
for d in detections:
a = (d.x_max - d.x_min) * (d.y_max-d.y_min)
if a > largest_area:
a = largest_area
largest = d
centerX = largest.x_min + largest.x_max/2
if centerX < midpoint-midpoint/6:
return 0 #on the left
if centerX > midpoint+midpoint/6:
return 2 #on the right
else:
return 1 #basically centered
async def main():
spinNum = 10 # when turning, spin the motor this much
straightNum = 300 # when going straight, spin motor this much
numCycles = 200 # run the loop X times
vel = 500 # go this fast when moving motor
# Connect to robot client and set up components
robot = await connect()
base = Base.from_robot(robot, 'base')
camera = Camera.from_robot(robot, "cam")
# Set up vision service with a color detector
vision = VisionServiceClient.from_robot(robot)
params = {'detect_color': '#a13b4c', 'hue_tolerance_pct': 0.06, 'segment_size': 1000}
myBallDet = VisModelConfig(name="ball_detector", type=VisModelType("color_detector"), parameters=params)
await vision.add_detector(myBallDet)
frame = await camera.get_image()
# Main loop. Detect the ball, determine if it's on the left or right, and head that way.
# Repeat this for numCycles
for i in range(numCycles):
detections = await vision.get_detections_from_camera("cam", "ball_detector")
answer = leftOrRight(detections, frame.size[0]/2)
if answer == 0:
print("left")
await base.spin(spinNum, vel) # CCW is positive
await base.move_straight(straightNum, vel)
if answer == 1:
print("center")
await base.move_straight(straightNum, vel)
if answer == 2:
print("right")
await base.spin(-spinNum, vel)
# If nothing is detected, nothing moves
await robot.close()
# To test your connection, run this instead of main()
async def test():
robot = await connect()
print('Resources:')
print(robot.resource_names)
if __name__ == '__main__':
print("Starting up... ")
asyncio.run(main())
print("Done.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment