Browse Source

Roboter comments added

master
Luis Waldhauser 1 year ago
parent
commit
445373a668

+ 9
- 0
software/roboter/ev3/drive_arm.py View File

#!/usr/bin/env python3 #!/usr/bin/env python3

"""
created by waldhauser

This file contains the programm to drive the arm back to middle
This file is needed for the color code drive operation
The plant where the robot is has to be passed as argument
"""

from ev3dev2.motor import Motor, OUTPUT_B, OUTPUT_C, SpeedPercent from ev3dev2.motor import Motor, OUTPUT_B, OUTPUT_C, SpeedPercent
import sys import sys



+ 9
- 2
software/roboter/ev3/drive_back.py View File

#!/usr/bin/env python3 #!/usr/bin/env python3

"""
created by waldhauser

This file contains the programm to drive the arm back to middle and drive the robot back to home
This file is needed for the hard code driving operations
The plant where the robot is has to be passed as argument
"""

from ev3dev2.motor import Motor, LargeMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent from ev3dev2.motor import Motor, LargeMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent
from ev3dev2.sensor.lego import TouchSensor, UltrasonicSensor from ev3dev2.sensor.lego import TouchSensor, UltrasonicSensor
from ev3dev2.sensor import INPUT_1, INPUT_4 from ev3dev2.sensor import INPUT_1, INPUT_4
motorRight.on(SpeedPercent(-25)) motorRight.on(SpeedPercent(-25))
break break



sensorTouch.wait_for_pressed(timeout_ms=None, sleep_ms=10) sensorTouch.wait_for_pressed(timeout_ms=None, sleep_ms=10)
motorLeft.off() motorLeft.off()
motorRight.off() motorRight.off()

+ 10
- 0
software/roboter/ev3/drive_back_straight.py View File

#!/usr/bin/env python3 #!/usr/bin/env python3

"""
created by waldhauser

This file contains the programm to drive the robot back to the starting position
This file is needed for the color code drive operation
No arguments are needed
The end is determined by the UltraSonic- and TouchSensor
"""

from ev3dev2.motor import LargeMotor, OUTPUT_A, OUTPUT_D, SpeedPercent from ev3dev2.motor import LargeMotor, OUTPUT_A, OUTPUT_D, SpeedPercent
from ev3dev2.sensor.lego import TouchSensor, UltrasonicSensor from ev3dev2.sensor.lego import TouchSensor, UltrasonicSensor
from ev3dev2.sensor import INPUT_1, INPUT_4 from ev3dev2.sensor import INPUT_1, INPUT_4

+ 6
- 4
software/roboter/ev3/drive_plant.py View File

#!/usr/bin/env pybricks-micropython #!/usr/bin/env pybricks-micropython
'''
Script to drive robot to plant.
Plant number is passed as argument.
'''


"""
created by waldhauser

This file contians the programm to drive to a specific plant based on the color codes
The plant where the robot is has to be passed as argument
"""


from ev3dev2.motor import Motor, LargeMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent from ev3dev2.motor import Motor, LargeMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent
from ev3dev2.sensor.lego import ColorSensor from ev3dev2.sensor.lego import ColorSensor

+ 0
- 65
software/roboter/ev3/drive_plant_gc.py View File

#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import Port, Stop, Direction, Button, Color
from pybricks.tools import wait, StopWatch, DataLog
from pybricks.robotics import DriveBase
from pybricks.media.ev3dev import SoundFile, ImageFile

import sys


def fun_1(ev3):
pass


def fun_2(a,b):
return 1

def move_1(mo_forward_1, mo_forward_2, mo_le_ri, mo_up_down):
wait(2000)
#move forward
mo_forward_1.run_target(500, 1250,wait=False)
mo_forward_2.run_target(500, 1250)

#move arm
mo_le_ri.run_target(200,-50)

#move sensors
mo_up_down.run_target(500,2500)
wait(2000)
mo_up_down.run_target(500,0)

#move arm
mo_le_ri.run_target(200,0)

#move backwards
mo_forward_1.run_target(500, 0,wait=False)
mo_forward_2.run_target(500, 0)



def move_2():
pass
def move_3():
pass




ev3 = EV3Brick()

motor_forward_1 = Motor(Port.A)
motor_forward_2 = Motor(Port.D)
motor_le_ri = Motor(Port.B, Direction.COUNTERCLOCKWISE, [8, 56]) #with gear for angle
motor_up_down = Motor(Port.C)

#n = int(sys.argv[1])

#if n == 1:
move_1(motor_forward_1,motor_forward_2,motor_le_ri,motor_up_down)




+ 6
- 0
software/roboter/ev3/plant_1.py View File

#!/usr/bin/env pybricks-micropython #!/usr/bin/env pybricks-micropython


"""
created by waldhauser

This file contians the programm to drive a specfic plant with a certain distance to drive
"""

from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent


motorRight = LargeMotor(OUTPUT_A) motorRight = LargeMotor(OUTPUT_A)

+ 6
- 0
software/roboter/ev3/plant_2.py View File

#!/usr/bin/env pybricks-micropython #!/usr/bin/env pybricks-micropython


"""
created by waldhauser

This file contians the programm to drive a specfic plant with a certain distance to drive
"""

from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent


motorRight = LargeMotor(OUTPUT_A) motorRight = LargeMotor(OUTPUT_A)

+ 6
- 0
software/roboter/ev3/plant_3.py View File

#!/usr/bin/env pybricks-micropython #!/usr/bin/env pybricks-micropython


"""
created by waldhauser

This file contians the programm to drive a specfic plant with a certain distance to drive
"""

from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent


motorRight = LargeMotor(OUTPUT_A) motorRight = LargeMotor(OUTPUT_A)

+ 6
- 0
software/roboter/ev3/plant_4.py View File

#!/usr/bin/env pybricks-micropython #!/usr/bin/env pybricks-micropython


"""
created by waldhauser

This file contians the programm to drive a specfic plant with a certain distance to drive
"""

from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent


motorRight = LargeMotor(OUTPUT_A) motorRight = LargeMotor(OUTPUT_A)

+ 6
- 0
software/roboter/ev3/plant_5.py View File

#!/usr/bin/env pybricks-micropython #!/usr/bin/env pybricks-micropython


"""
created by waldhauser

This file contians the programm to drive a specfic plant with a certain distance to drive
"""

from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent


motorRight = LargeMotor(OUTPUT_A) motorRight = LargeMotor(OUTPUT_A)

+ 6
- 0
software/roboter/ev3/plant_6.py View File

#!/usr/bin/env pybricks-micropython #!/usr/bin/env pybricks-micropython


"""
created by waldhauser

This file contians the programm to drive a specfic plant with a certain distance to drive
"""

from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent from ev3dev2.motor import Motor, LargeMotor, ServoMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent


motorRight = LargeMotor(OUTPUT_A) motorRight = LargeMotor(OUTPUT_A)

+ 39
- 7
software/roboter/raspy/functions.py View File

"""
created by waldhauser

This file contains the functions for the mainProg.py.
The functions are part of three groups, MQTT-callbacks, functions for external threads and one normal function.
"""

import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
import json import json
import threading import threading
sensorData["ActionID"] = actionID sensorData["ActionID"] = actionID
client.publish(Topics["ROBOT_DATA_SENSORDATA"], json.dumps(sensorData, indent=4), qos=1) client.publish(Topics["ROBOT_DATA_SENSORDATA"], json.dumps(sensorData, indent=4), qos=1)


#region Thread
# Functions to be executed in external Thread to not block the mainProg
# Functions contain the drive and sensor measurement operations


def drive_plant_thread(plantID, actionID, client: mqtt.Client): def drive_plant_thread(plantID, actionID, client: mqtt.Client):
""" """
Function to drive to plant according to number from MQTT message in thread Function to drive to plant according to number from MQTT message in thread
Drive programm based on hardcoded drive programms specific for each plant
Only possible to drive to one plant per execution
Meassure and publish data via MQTT Meassure and publish data via MQTT
Drive home to starting point Drive home to starting point


***If color codes are working properly this function is not needed anymore***

Args: Args:
plantID (_type_): plant to measure plantID (_type_): plant to measure
actionID (_type_): current ID of driving action actionID (_type_): current ID of driving action
client (mqtt.Client): current mqtt client for publishing client (mqtt.Client): current mqtt client for publishing
""" """
# FIXME Change to color code driving
errorCode = os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/plant_{plantID}.py') errorCode = os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/plant_{plantID}.py')
# errorCode = os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/drive_plant.py {plantID}')


if errorCode != 0: if errorCode != 0:
if errorCode == 65280: if errorCode == 65280:


def drive_plant_all_thread(plantIDs: list, actionID, client: mqtt.Client): def drive_plant_all_thread(plantIDs: list, actionID, client: mqtt.Client):
""" """
Function to drive to plants according to numbers from MQTT message in thread
Function to drive to plants according to numbers from MQTT message in thread, one or more plants possible
PlantIDs have to be in ascending order
Drive programm based on color codes in the flowerbed
Meassure and publish data for all plants via MQTT Meassure and publish data for all plants via MQTT
Drive home to starting point Drive home to starting point


***If color codes are working properly, only this function is needed for drive operations***

Args: Args:
plantIDs (list): Plants to drive to
plantIDs (list): Plants to drive to, plants have to be in ascending order
actionID (_type_): ActionID from Backend for whole drive action actionID (_type_): ActionID from Backend for whole drive action
client (mqtt.Client): current MQTT client client (mqtt.Client): current MQTT client
""" """
return return


# Read Sensors and store data, take picture
logging.info("Measuring Sensors") logging.info("Measuring Sensors")
try: try:
sensordata = {} sensordata = {}
logging.info("Robot home") logging.info("Robot home")
client.publish(Topics["ROBOT_DATA_ROBOTREADY"], "True", qos=1) client.publish(Topics["ROBOT_DATA_ROBOTREADY"], "True", qos=1)


#endregion


#region MQTT callbacks #region MQTT callbacks
# Functions to be called by the MQTT callbacks
# Starting the drive operations in threads or executing the small operations directly


def drive_plant(client: mqtt.Client, userdata, message: mqtt.MQTTMessage): def drive_plant(client: mqtt.Client, userdata, message: mqtt.MQTTMessage):
""" """
Function to drive to plant according to request Function to drive to plant according to request
Starting Drive in Thread to not block main programm Starting Drive in Thread to not block main programm


***If color codes are working properly this function is not needed anymore***

Args: Args:
client (mqtt.Client): current mqtt client client (mqtt.Client): current mqtt client
userdata (_type_): _description_ userdata (_type_): _description_
Function to drive to plants according to request Function to drive to plants according to request
Starting Drive in Thread to not block main programm Starting Drive in Thread to not block main programm


***If color codes are working properly, only this function is needed for drive operations***

Args: Args:
client (mqtt.Client): current MQTT client client (mqtt.Client): current MQTT client
userdata (_type_): _description_ userdata (_type_): _description_
thread = threading.Thread(target= drive_plant_all_thread, args=(plantIDs, actionID, client), daemon=True) thread = threading.Thread(target= drive_plant_all_thread, args=(plantIDs, actionID, client), daemon=True)
thread.start() thread.start()



def get_position(clients: mqtt.Client, userdata, message: mqtt.MQTTMessage): def get_position(clients: mqtt.Client, userdata, message: mqtt.MQTTMessage):
""" """
Callback function for GPS position request Callback function for GPS position request
Function to send actual GPS position via MQTT in form of POSITION Function to send actual GPS position via MQTT in form of POSITION


***Not implemented, available GPS-sensor was not working***

Args: Args:
client (mqtt.Client): current mqtt client client (mqtt.Client): current mqtt client
userdata (_type_): _description_ userdata (_type_): _description_
def get_batteryStatus(client: mqtt.Client, userdata, message: mqtt.MQTTMessage): def get_batteryStatus(client: mqtt.Client, userdata, message: mqtt.MQTTMessage):
""" """
Callback function for battery status request Callback function for battery status request
Function to read battery status from ev3 and send via MQTT in form of BATTERY
Function to read battery status from EV3 and send via MQTT in form of BATTERY
Reading battery level via SSH script execution
Battery level shown in Volts:
8,5V -> 100% 8,5V -> 100%
5V -> 0% 5V -> 0%


client.publish(Topics["ROBOT_DATA_ERROR"], "Robot not connected", qos=1) client.publish(Topics["ROBOT_DATA_ERROR"], "Robot not connected", qos=1)
return return


batteryLevel = round(batteryLevel / 1000000, 2) # Voltage
batteryLevel = round(batteryLevel / 1000000, 2) # Conversion to Volt
batteryLevel = batteryLevel - 5 batteryLevel = batteryLevel - 5
batteryLevel = round(batteryLevel / 3.5, 3) *100 # Percentage
batteryLevel = round(batteryLevel / 3.5, 3) *100 # Conversion to Percentage, 8,5V -> 100%, 5V -> 0%


battery = { battery = {
"Battery": batteryLevel "Battery": batteryLevel
""" """
Takes picture and publish via MQTT Takes picture and publish via MQTT


***Pictures can not be send until now -> assumption of reaching maximum payload limit***

Args: Args:
client (mqtt.Client): current mqtt client client (mqtt.Client): current mqtt client
""" """

+ 3
- 3
software/roboter/raspy/mainProg.py View File

""" """
created by waldluis
created by waldlhauser


This file contains the main script for the RaspberryPi of smart garden project This file contains the main script for the RaspberryPi of smart garden project
It has the task to control the EV3 robot and take measurements with the mounted sensor
It has the task to control the EV3 robot and take measurements with the mounted sensors
The sensor data is published to MQTT topics to be available for the backend server The sensor data is published to MQTT topics to be available for the backend server
Used protocol for interaction: mqtt (paho-mqtt module) Used protocol for interaction: mqtt (paho-mqtt module)
Interaction with the EV3 via SSH Interaction with the EV3 via SSH
"""
"""


import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
import functions import functions

+ 20
- 15
software/roboter/raspy/raspy_sensors.py View File

# from picamera import PiCamera
"""
created by waldhauser

This file contains the functions to read the sensors DHT22, TSL2561, earth humidity with MCP3008 ADC and RaspberryPi camera
Every sensor can be read on its own
Reading all sensors is possible with the readSensors() function and provides the data in the format of SENSORDATA dictionary
"""

import adafruit_dht import adafruit_dht
import adafruit_tsl2561 import adafruit_tsl2561
import board import board
percentage = round(((1100 - percentage) / 1100) *100, 2) # 680 -> 100% moisture, 1780 -> 0% moisture percentage = round(((1100 - percentage) / 1100) *100, 2) # 680 -> 100% moisture, 1780 -> 0% moisture


if percentage > 100 or percentage < 0: # If not connected values above 100% appear if percentage > 100 or percentage < 0: # If not connected values above 100% appear
percentage = 0
raise Exception("YL69 not connected") raise Exception("YL69 not connected")


return percentage return percentage
def readSensors(sensorData): def readSensors(sensorData):
""" """
Read DHT22, TSL2561 and Humidity Sensor Read DHT22, TSL2561 and Humidity Sensor
Dictionary is passed to ensure that values are available when errors occur


Args: Args:
sensorData (dictionary): Dictionary of type SENSORDATA sensorData (dictionary): Dictionary of type SENSORDATA
try: try:
sensorData["AirTemperature"], sensorData["AirHumidity"] = readDHT22() sensorData["AirTemperature"], sensorData["AirHumidity"] = readDHT22()
except Exception as e: except Exception as e:
sensorData["AirHumidity"] = 0 # otherwise old value
sensorData["AirHumidity"] = 0 # No value returend if error occurs -> setting dummy value
sensorData["AirTemperature"] = 0 sensorData["AirTemperature"] = 0
errorMessage = str(e) + "\n"
errorMessage = str(e) + "\n" # Appending received error message to later forward all occured errors


# read TSL2561 # read TSL2561
try: try:
sensorData["Brightness"] = readTSL2561() sensorData["Brightness"] = readTSL2561()
except Exception as e: except Exception as e:
sensorData["Brightness"] = 0 # otherwise old value
errorMessage = errorMessage + str(e) + "\n"
sensorData["Brightness"] = 0 # No value returend if error occurs -> setting dummy value
errorMessage = errorMessage + str(e) + "\n" # Appending received error message to later forward all occured errors


# read YL-69 # read YL-69
try: try:
sensorData["SoilMoisture"] = readMCP3008() sensorData["SoilMoisture"] = readMCP3008()
except Exception as e: except Exception as e:
sensorData["SoilMoisture"] = 0
errorMessage = errorMessage + str(e) + "\n"
sensorData["SoilMoisture"] = 0 # No value returend if error occurs -> setting dummy value
errorMessage = errorMessage + str(e) + "\n" # Appending received error message to later forward all occured errors


# combined error message
# raise combined error message
if errorMessage != "": if errorMessage != "":
raise Exception(errorMessage) raise Exception(errorMessage)


def takePicture(): def takePicture():
""" """
Take picture and return picture
Returns:
_type_: _description_
Take picture and store as "picture.png" in current folder

""" """
try: try:
camera = PiCamera() camera = PiCamera()
camera.capture("picture.png") camera.capture("picture.png")
camera.stop_preview() camera.stop_preview()


return



# TODO - read position with sensor # TODO - read position with sensor
def readPosition(): def readPosition():
""" """
Read and return Position Read and return Position


***Not implemented, available GPS-sensor was not working***

Returns: Returns:
_type_: _description_ _type_: _description_
""" """




# Testing # Testing

def main(): def main():
value = SENSORDATA value = SENSORDATA
try: try:

Loading…
Cancel
Save