Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
F
Farmbot Yolo
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Robotlab
Farmbot Yolo
Commits
67cbe20e
Unverified
Commit
67cbe20e
authored
Jun 13, 2022
by
Anton Tetov Johansson
Browse files
Options
Downloads
Patches
Plain Diff
makefile fix and cleanup
parent
548b938b
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
Makefile
+2
-4
2 additions, 4 deletions
Makefile
src/utils/client.py
+218
-171
218 additions, 171 deletions
src/utils/client.py
with
220 additions
and
175 deletions
Makefile
+
2
−
4
View file @
67cbe20e
.DEFAULT_GOAL
:=
default
LIBSO
=
1
export
LIBSO
darknet
:
git submodule init
git submodule update
default
:
darknet
$(
MAKE
)
-C
darknet
.PHONY
:
default
$(
MAKE
)
LIBSO
=
$(
LIBSO
)
-C
darknet
.PHONY
:
default darknet
This diff is collapsed.
Click to expand it.
src/utils/client.py
+
218
−
171
View file @
67cbe20e
'''
Communicate with the server at the manufacturer
"""
Communicate with the server at the manufacturer.
Not useful for the local drive script
'''
"""
import
paho.mqtt.client
as
mqtt
import
json
import
time
...
...
@@ -17,13 +17,23 @@ MAX_Z = 469 # TODO test this one!
def
coord
(
x
,
y
,
z
):
return
{
"
kind
"
:
"
coordinate
"
,
"
args
"
:
{
"
x
"
:
x
,
"
y
"
:
y
,
"
z
"
:
z
}}
# 返回json 嵌套对象
def
move_request
(
x
,
y
,
z
):
return
{
"
kind
"
:
"
rpc_request
"
,
# 返回 json对象,对象内含数组
return
{
"
kind
"
:
"
rpc_request
"
,
# 返回 json对象,对象内含数组
"
args
"
:
{
"
label
"
:
""
},
"
body
"
:
[{
"
kind
"
:
"
move_absolute
"
,
"
args
"
:
{
"
location
"
:
coord
(
x
,
y
,
z
),
"
body
"
:
[
{
"
kind
"
:
"
move_absolute
"
,
"
args
"
:
{
"
location
"
:
coord
(
x
,
y
,
z
),
"
offset
"
:
coord
(
0
,
0
,
0
),
"
speed
"
:
100
}}]}
"
speed
"
:
100
,
},
}
],
}
def
read_pin_request
(
pin_number
,
pin_mode
=
"
digital
"
):
modes
=
{
"
digital
"
:
0
,
"
analog
"
:
1
}
...
...
@@ -31,14 +41,21 @@ def read_pin_request(pin_number, pin_mode="digital"):
if
pin_mode
!=
"
digital
"
:
raise
NotImplementedError
()
return
{
"
kind
"
:
"
rpc_request
"
,
return
{
"
kind
"
:
"
rpc_request
"
,
"
args
"
:
{
"
label
"
:
""
},
"
body
"
:
[{
"
kind
"
:
"
read_pin
"
,
"
body
"
:
[
{
"
kind
"
:
"
read_pin
"
,
"
args
"
:
{
"
label
"
:
"
pin
"
+
str
(
pin_number
),
"
pin_mode
"
:
modes
[
pin_mode
]
or
(
modes
[
"
digital
"
]),
"
pin_number
"
:
pin_number
}}]}
"
pin_number
"
:
pin_number
,
},
}
],
}
def
write_pin_request
(
pin_number
,
pin_value
,
pin_mode
=
"
digital
"
):
modes
=
{
"
digital
"
:
0
,
"
analog
"
:
1
}
...
...
@@ -46,41 +63,54 @@ def write_pin_request(pin_number, pin_value, pin_mode="digital"):
if
pin_mode
!=
"
digital
"
:
raise
NotImplementedError
()
return
{
"
kind
"
:
"
rpc_request
"
,
return
{
"
kind
"
:
"
rpc_request
"
,
"
args
"
:
{
"
label
"
:
""
},
"
body
"
:
[{
"
kind
"
:
"
write_pin
"
,
"
body
"
:
[
{
"
kind
"
:
"
write_pin
"
,
"
args
"
:
{
"
pin_mode
"
:
modes
[
pin_mode
]
or
(
modes
[
"
digital
"
]),
"
pin_number
"
:
pin_number
,
"
pin_value
"
:
pin_value
"
pin_value
"
:
pin_value
,
},
}
],
}
]
}
def
toggle_pin_request
(
pin_number
):
return
{
"
kind
"
:
"
rpc_request
"
,
return
{
"
kind
"
:
"
rpc_request
"
,
"
args
"
:
{
"
label
"
:
""
},
"
body
"
:
[{
"
kind
"
:
"
toggle_pin
"
,
"
body
"
:
[
{
"
kind
"
:
"
toggle_pin
"
,
"
args
"
:
{
"
pin_number
"
:
pin_number
,
},
}
}
]
],
}
def
take_photo_request
():
return
{
"
kind
"
:
"
rpc_request
"
,
return
{
"
kind
"
:
"
rpc_request
"
,
"
args
"
:
{
"
label
"
:
""
},
# label空着是为了在blocking_request中填上uuid,唯一识别码
"
body
"
:
[{
"
kind
"
:
"
take_photo
"
,
"
args
"
:
{}}]}
"
body
"
:
[{
"
kind
"
:
"
take_photo
"
,
"
args
"
:
{}}],
}
def
clip
(
v
,
min_v
,
max_v
):
if
v
<
min_v
:
return
min_v
if
v
>
max_v
:
return
max_v
if
v
<
min_v
:
return
min_v
if
v
>
max_v
:
return
max_v
return
v
class
FarmbotClient
(
object
):
class
FarmbotClient
(
object
):
def
__init__
(
self
,
device_id
,
token
):
self
.
device_id
=
device_id
...
...
@@ -89,21 +119,24 @@ class FarmbotClient(object):
self
.
client
.
on_connect
=
self
.
_on_connect
# ???
self
.
client
.
on_message
=
self
.
_on_message
logging
.
basicConfig
(
level
=
logging
.
DEBUG
,
logging
.
basicConfig
(
level
=
logging
.
DEBUG
,
format
=
"
%(asctime)s
\t
%(name)s
\t
%(levelname)s
\t
%(message)s
"
,
filename
=
'
farmbot_client.log
'
,
filemode
=
'
a
'
)
filename
=
"
farmbot_client.log
"
,
filemode
=
"
a
"
,
)
console
=
logging
.
StreamHandler
()
console
.
setLevel
(
logging
.
INFO
)
console
.
setFormatter
(
logging
.
Formatter
(
"
%(asctime)s
\t
%(message)s
"
))
logging
.
getLogger
(
''
).
addHandler
(
console
)
logging
.
getLogger
(
""
).
addHandler
(
console
)
self
.
connected
=
False
self
.
client
.
connect
(
"
clever-octopus.rmq.cloudamqp.com
"
,
1883
,
60
)
#前面的url要运行按README.md中request_token.py 后面俩是TCP Port, Websocket Port
self
.
client
.
connect
(
"
clever-octopus.rmq.cloudamqp.com
"
,
1883
,
60
)
# 前面的url要运行按README.md中request_token.py 后面俩是TCP Port, Websocket Port
self
.
client
.
loop_start
()
# 初始化函数里就会连接到服务器上,所以每次实例化一个新的client时,就已经连上了
def
shutdown
(
self
):
self
.
client
.
disconnect
()
self
.
client
.
loop_stop
()
...
...
@@ -113,7 +146,9 @@ class FarmbotClient(object):
y
=
clip
(
y
,
0
,
MAX_Y
)
z
=
clip
(
z
,
0
,
MAX_Z
)
status_ok
=
self
.
_blocking_request
(
move_request
(
x
,
y
,
z
))
# 发请求
logging
.
info
(
"
MOVE (%s,%s,%s) [%s]
"
,
x
,
y
,
z
,
status_ok
)
#存日志,包括执行了什么“move x y z +返回值 ”
logging
.
info
(
"
MOVE (%s,%s,%s) [%s]
"
,
x
,
y
,
z
,
status_ok
)
# 存日志,包括执行了什么“move x y z +返回值 ”
def
take_photo
(
self
):
# TODO: is this enough? it's issue a request for the photo, but is the actual capture async?
...
...
@@ -121,12 +156,18 @@ class FarmbotClient(object):
logging
.
info
(
"
TAKE_PHOTO [%s]
"
,
status_ok
)
def
read_pin
(
self
,
pin_number
,
pin_mode
=
"
digital
"
):
status_ok
=
self
.
_blocking_request
(
read_pin_request
(
pin_number
,
pin_mode
=
pin_mode
))
status_ok
=
self
.
_blocking_request
(
read_pin_request
(
pin_number
,
pin_mode
=
pin_mode
)
)
logging
.
info
(
f
"
READ PIN (pin_number:
{
pin_number
}
) [
{
status_ok
}
]
"
)
def
write_pin
(
self
,
pin_number
,
pin_value
,
pin_mode
=
"
digital
"
):
status_ok
=
self
.
_blocking_request
(
write_pin_request
(
pin_number
,
pin_value
,
pin_mode
=
pin_mode
))
logging
.
info
(
f
"
WRITE PIN (pin_number:
{
pin_number
}
, pin_value:
{
pin_value
}
) [
{
status_ok
}
]
"
)
status_ok
=
self
.
_blocking_request
(
write_pin_request
(
pin_number
,
pin_value
,
pin_mode
=
pin_mode
)
)
logging
.
info
(
f
"
WRITE PIN (pin_number:
{
pin_number
}
, pin_value:
{
pin_value
}
) [
{
status_ok
}
]
"
)
def
toggle_pin
(
self
,
pin_number
):
status_ok
=
self
.
_blocking_request
(
toggle_pin_request
(
pin_number
))
...
...
@@ -134,19 +175,23 @@ class FarmbotClient(object):
def
_blocking_request
(
self
,
request
,
retries_remaining
=
3
):
if
retries_remaining
==
0
:
logging
.
error
(
"
< blocking request [%s] OUT OF RETRIES
"
,
request
)
#尝试3次,然后在日志中记录错误
logging
.
error
(
"
< blocking request [%s] OUT OF RETRIES
"
,
request
)
# 尝试3次,然后在日志中记录错误
return
False
self
.
_wait_for_connection
()
# 在哪定义的?
# assign a new uuid for this attempt
self
.
pending_uuid
=
str
(
uuid4
())
request
[
'
args
'
][
'
label
'
]
=
self
.
pending_uuid
#
接收move_request函数的json对象
request
[
"
args
"
][
"
label
"
]
=
self
.
pending_uuid
#
接收move_request函数的json对象
logging
.
debug
(
"
> blocking request [%s] retries=%d
"
,
request
,
retries_remaining
)
# send request off 发送请求
self
.
rpc_status
=
None
self
.
client
.
publish
(
"
bot/
"
+
self
.
device_id
+
"
/from_clients
"
,
json
.
dumps
(
request
))
self
.
client
.
publish
(
"
bot/
"
+
self
.
device_id
+
"
/from_clients
"
,
json
.
dumps
(
request
)
)
# wait for response
timeout_counter
=
600
# ~1min 等待1s
...
...
@@ -159,12 +204,12 @@ class FarmbotClient(object):
self
.
pending_uuid
=
None
# if it's ok, we're done!
if
self
.
rpc_status
==
'
rpc_ok
'
:
if
self
.
rpc_status
==
"
rpc_ok
"
:
logging
.
debug
(
"
< blocking request OK [%s]
"
,
request
)
return
True
# if it's not ok, wait a bit and retry
if
self
.
rpc_status
==
'
rpc_error
'
:
if
self
.
rpc_status
==
"
rpc_error
"
:
logging
.
warn
(
"
< blocking request ERROR [%s]
"
,
request
)
time
.
sleep
(
1
)
return
self
.
_blocking_request
(
request
,
retries_remaining
-
1
)
...
...
@@ -174,7 +219,6 @@ class FarmbotClient(object):
logging
.
error
(
msg
)
raise
Exception
(
msg
)
def
_wait_for_connection
(
self
):
# TODO: better way to do all this async event driven rather than with polling :/
timeout_counter
=
600
# ~1min
...
...
@@ -192,7 +236,10 @@ class FarmbotClient(object):
def
_on_message
(
self
,
client
,
userdata
,
msg
):
resp
=
json
.
loads
(
msg
.
payload
.
decode
())
if
resp
[
'
args
'
][
'
label
'
]
!=
'
ping
'
:
if
resp
[
"
args
"
][
"
label
"
]
!=
"
ping
"
:
logging
.
debug
(
"
> _on_message [%s] [%s]
"
,
msg
.
topic
,
resp
)
if
msg
.
topic
.
endswith
(
"
/from_device
"
)
and
resp
[
'
args
'
][
'
label
'
]
==
self
.
pending_uuid
:
self
.
rpc_status
=
resp
[
'
kind
'
]
if
(
msg
.
topic
.
endswith
(
"
/from_device
"
)
and
resp
[
"
args
"
][
"
label
"
]
==
self
.
pending_uuid
):
self
.
rpc_status
=
resp
[
"
kind
"
]
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment