Last active
February 7, 2023 23:11
-
-
Save mestcihazal/e78e3b29c58aa301c9a197ada272e6a0 to your computer and use it in GitHub Desktop.
Scuttle code for following a red object
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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