Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
larm-astro
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Inès EL HADRI
larm-astro
Commits
9592cb01
Commit
9592cb01
authored
Jan 17, 2024
by
Inès EL HADRI
💤
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
merge cam_driver and cam_vision
parent
160556fa
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
80 additions
and
82 deletions
+80
-82
.gitignore
.gitignore
+2
-1
CMakeLists.txt
grp_astro/CMakeLists.txt
+1
-1
simulation_launch.yaml
grp_astro/launch/simulation_launch.yaml
+0
-3
tbot_launch.yaml
grp_astro/launch/tbot_launch.yaml
+0
-6
cam_driver.py
grp_astro/src/cam_driver.py
+45
-27
cam_vision
grp_astro/src/cam_vision
+32
-44
No files found.
.gitignore
View file @
9592cb01
/.env
/.env
**/build
**/build
**/install
**/install
**/log
**/log
\ No newline at end of file
**/__pycache__
\ No newline at end of file
grp_astro/CMakeLists.txt
View file @
9592cb01
...
@@ -45,7 +45,7 @@ install(DIRECTORY
...
@@ -45,7 +45,7 @@ install(DIRECTORY
# Python scripts
# Python scripts
install
(
PROGRAMS
install
(
PROGRAMS
src/cam_driver
src/cam_driver
.py
src/cam_vision
src/cam_vision
src/reactive_move
src/reactive_move
src/scan2point_cloud
src/scan2point_cloud
...
...
grp_astro/launch/simulation_launch.yaml
View file @
9592cb01
...
@@ -45,9 +45,6 @@ launch:
...
@@ -45,9 +45,6 @@ launch:
from
:
'
/cam_rgb'
from
:
'
/cam_rgb'
to
:
'
/camera/image_raw'
to
:
'
/camera/image_raw'
-
executable
:
cmd
:
gnome-terminal --tab -e 'ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args --remap turtle1/cmd_vel:=/cmd_vel'
# Launch a SLAM algorithm
# Launch a SLAM algorithm
-
include
:
-
include
:
file
:
"
$(find-pkg-share
slam_toolbox)/launch/online_sync_launch.py"
file
:
"
$(find-pkg-share
slam_toolbox)/launch/online_sync_launch.py"
\ No newline at end of file
grp_astro/launch/tbot_launch.yaml
View file @
9592cb01
...
@@ -20,12 +20,6 @@ launch:
...
@@ -20,12 +20,6 @@ launch:
from
:
'
/cmd_vel'
from
:
'
/cmd_vel'
to
:
'
/multi/cmd_nav'
to
:
'
/multi/cmd_nav'
# Publish camera views
-
node
:
pkg
:
"
grp_astro"
exec
:
"
cam_driver"
name
:
"
cam_driver"
# Publish if there is a bottle in the field of view
# Publish if there is a bottle in the field of view
-
node
:
-
node
:
pkg
:
"
grp_astro"
pkg
:
"
grp_astro"
...
...
grp_astro/src/cam_driver
→
grp_astro/src/cam_driver
.py
View file @
9592cb01
...
@@ -14,29 +14,38 @@ class CameraDriver(Node):
...
@@ -14,29 +14,38 @@ class CameraDriver(Node):
def
__init__
(
self
,
name
=
"cam_driver"
,
timerFreq
=
1
/
60.0
):
def
__init__
(
self
,
name
=
"cam_driver"
,
timerFreq
=
1
/
60.0
):
super
()
.
__init__
(
name
)
# Create the node
super
()
.
__init__
(
name
)
# Create the node
# Initialize publishers
# Initialize publishers:
self
.
init_publishers
(
timerFreq
)
# Initialize camera
self
.
_init_camera
()
def
init_publishers
(
self
,
timerFreq
:
float
):
"""
Initialize Publishers
"""
self
.
_rgb_publisher
=
self
.
create_publisher
(
Image
,
'cam_rgb'
,
10
)
self
.
_rgb_publisher
=
self
.
create_publisher
(
Image
,
'cam_rgb'
,
10
)
self
.
_depth_publisher
=
self
.
create_publisher
(
Image
,
'cam_depth'
,
10
)
self
.
_depth_publisher
=
self
.
create_publisher
(
Image
,
'cam_depth'
,
10
)
self
.
_depth_dist_publisher
=
self
.
create_publisher
(
Float32MultiArray
,
'cam_depth_dist'
,
10
)
self
.
_infra_publisher_1
=
self
.
create_publisher
(
Image
,
'cam_infra_1'
,
10
)
self
.
_infra_publisher_1
=
self
.
create_publisher
(
Image
,
'cam_infra_1'
,
10
)
self
.
_infra_publisher_2
=
self
.
create_publisher
(
Image
,
'cam_infra_2'
,
10
)
self
.
_infra_publisher_2
=
self
.
create_publisher
(
Image
,
'cam_infra_2'
,
10
)
# Initialize a clock for the publisher
# Initialize a clock for the publisher
self
.
create_timer
(
timerFreq
,
self
.
publish_imgs
)
self
.
create_timer
(
timerFreq
,
self
.
publish_imgs
)
def
_init_camera
(
self
):
# ------------------------------ Initialize camera ------------------------------ #
"""
Initialize camera
"""
## Configure depth and color streams
## Configure depth and color streams
self
.
_pipeline
=
rs
.
pipeline
()
self
.
_pipeline
=
rs
.
pipeline
()
self
.
_config
=
rs
.
config
()
self
.
_config
=
rs
.
config
()
self
.
_colorizer
=
rs
.
colorizer
()
self
.
_colorizer
=
rs
.
colorizer
()
self
.
_align_to
=
rs
.
stream
.
depth
self
.
_align_to
=
rs
.
stream
.
color
self
.
_align
=
rs
.
align
(
self
.
_align_to
)
self
.
_align
=
rs
.
align
(
self
.
_align_to
)
self
.
_color_info
=
(
0
,
0
,
255
)
self
.
_color_info
=
(
0
,
0
,
255
)
## Get device product line for setting a supporting resolution
## Get device product line for setting a supporting resolution
pipeline_wrapper
=
rs
.
pipeline_wrapper
(
self
.
_pipeline
)
pipeline_wrapper
=
rs
.
pipeline_wrapper
(
self
.
_pipeline
)
pipeline_profile
=
self
.
_config
.
resolve
(
pipeline_wrapper
)
pipeline_profile
=
self
.
_config
.
resolve
(
pipeline_wrapper
)
...
@@ -63,36 +72,42 @@ class CameraDriver(Node):
...
@@ -63,36 +72,42 @@ class CameraDriver(Node):
## Start the acquisition
## Start the acquisition
self
.
_pipeline
.
start
(
self
.
_config
)
self
.
_pipeline
.
start
(
self
.
_config
)
def
read_imgs
(
self
):
def
_update_imgs
(
self
):
"""lire et traduire images camera"""
"""
Update self images parameters
self._color_frame, self._depth_dist_frame, self._infra_frame_1, self._infra_frame_2
"""
# Get frames
# Get frames
frames
=
self
.
_pipeline
.
wait_for_frames
()
frames
=
self
.
_pipeline
.
wait_for_frames
()
# Split frames
# Split frames
color_frame
=
frames
.
first
(
rs
.
stream
.
color
)
aligned_frames
=
self
.
_align
.
process
(
frames
)
aligned_frames
=
self
.
_align
.
process
(
frames
)
depth_dist_frame
=
aligned_frames
.
get_depth_frame
()
#color_frame = aligned_frames.get_color_frame()
infra_frame_1
=
frames
.
get_infrared_frame
(
1
)
infra_frame_2
=
frames
.
get_infrared_frame
(
2
)
#self._color_frame = frames.first(rs.stream.color)
self
.
_color_frame
=
aligned_frames
.
get_color_frame
()
self
.
_depth_dist_frame
=
aligned_frames
.
get_depth_frame
()
self
.
_infra_frame_1
=
frames
.
get_infrared_frame
(
1
)
self
.
_infra_frame_2
=
frames
.
get_infrared_frame
(
2
)
return
None
if
(
self
.
_color_frame
and
self
.
_depth_dist_frame
and
self
.
_infra_frame_1
and
self
.
_infra_frame_2
)
is
None
else
1
def
read_imgs
(
self
):
"""
Read and convert images to ROS - only to publish ros images
"""
self
.
_update_imgs
()
if
not
(
depth_dist_frame
and
aligned_frames
and
color_frame
and
infra_frame_1
and
infra_frame_2
):
if
not
(
self
.
_depth_dist_frame
and
self
.
_color_frame
and
self
.
_infra_frame_1
and
self
.
_
infra_frame_2
):
return
return
# Convert images to numpy arrays
# Convert images to numpy arrays
color_intrin
=
color_frame
.
profile
.
as_video_stream_profile
()
.
intrinsics
color_image
=
np
.
asanyarray
(
self
.
_color_frame
.
get_data
())
depth_image
=
np
.
asanyarray
(
depth_dist_frame
.
get_data
())
infra_image_1
=
np
.
asanyarray
(
self
.
_infra_frame_1
.
get_data
())
depth_dist
=
np
.
zeros
((
848
,
480
))
infra_image_2
=
np
.
asanyarray
(
self
.
_infra_frame_2
.
get_data
())
for
y
in
range
(
480
):
for
x
in
range
(
848
):
depth
=
depth_dist_frame
.
get_distance
(
x
,
y
)
dx
,
dy
,
dz
=
rs
.
rs2_deproject_pixel_to_point
(
color_intrin
,
[
x
,
y
],
depth
)
depth_dist
[
x
,
y
]
=
math
.
sqrt
(
dx
**
2
+
dy
**
2
+
dz
**
2
)
color_image
=
np
.
asanyarray
(
color_frame
.
get_data
())
infra_image_1
=
np
.
asanyarray
(
infra_frame_1
.
get_data
())
infra_image_2
=
np
.
asanyarray
(
infra_frame_2
.
get_data
())
# Apply colormap on depth and IR images (image must be converted to 8-bit per pixel first)
# Apply colormap on depth and IR images (image must be converted to 8-bit per pixel first)
depth_colormap
=
cv2
.
applyColorMap
(
cv2
.
convertScaleAbs
(
depth_image
,
alpha
=
0.03
),
cv2
.
COLORMAP_JET
)
depth_colormap
=
cv2
.
applyColorMap
(
cv2
.
convertScaleAbs
(
depth_image
,
alpha
=
0.03
),
cv2
.
COLORMAP_JET
)
...
@@ -134,6 +149,9 @@ class CameraDriver(Node):
...
@@ -134,6 +149,9 @@ class CameraDriver(Node):
return
self
.
_rgb_image
,
self
.
_depth_image
,
self
.
_infra1_image
,
self
.
_infra2_image
return
self
.
_rgb_image
,
self
.
_depth_image
,
self
.
_infra1_image
,
self
.
_infra2_image
def
publish_imgs
(
self
):
def
publish_imgs
(
self
):
"""
publish ros images
"""
self
.
publish_rgb
()
self
.
publish_rgb
()
self
.
publish_depth
()
self
.
publish_depth
()
self
.
publish_IR
()
self
.
publish_IR
()
...
...
grp_astro/src/cam_vision
View file @
9592cb01
...
@@ -4,30 +4,31 @@ from rclpy.node import Node
...
@@ -4,30 +4,31 @@ from rclpy.node import Node
from
sensor_msgs.msg
import
Image
from
sensor_msgs.msg
import
Image
from
std_msgs.msg
import
String
,
Float32MultiArray
from
std_msgs.msg
import
String
,
Float32MultiArray
import
numpy
as
np
import
numpy
as
np
import
sys
,
cv2
,
pathlib
,
statistics
import
cv2
,
pathlib
,
statistics
from
cv_bridge
import
CvBridge
from
cv_bridge
import
CvBridge
from
cam_driver
import
CameraDriver
import
pyrealsense2
as
rs
import
math
class
CameraVision
(
Node
):
class
CameraVision
(
CameraDriver
):
def
__init__
(
self
,
name
=
"cam_vision"
,
timerFreq
=
1
/
60.0
):
def
__init__
(
self
,
name
=
"cam_vision"
,
timerFreq
=
1
/
60.0
):
super
()
.
__init__
(
name
)
# Create the node
super
()
.
__init__
(
name
,
timerFreq
)
# Create the node
# Initialiaze node variables
# Initialize node variables
self
.
_low
=
np
.
array
([
60
-
25
,
50
,
50
])
self
.
_low
=
np
.
array
([
60
-
25
,
50
,
50
])
self
.
_high
=
np
.
array
([
65
+
25
,
255
,
255
])
self
.
_high
=
np
.
array
([
65
+
25
,
255
,
255
])
self
.
_kernel
=
np
.
ones
((
5
,
5
),
np
.
uint8
)
self
.
_kernel
=
np
.
ones
((
5
,
5
),
np
.
uint8
)
self
.
_color_info
=
(
0
,
0
,
255
)
self
.
_color_info
=
(
0
,
0
,
255
)
# Initialize subscribers
# Initialize a ROS2 Image to CV2 image converter
self
.
create_subscription
(
Image
,
'cam_rgb'
,
self
.
rgb_callback
,
10
)
self
.
_bridge
=
CvBridge
()
self
.
create_subscription
(
Float32MultiArray
,
'cam_depth_dist'
,
self
.
depth_callback
,
10
)
# Initialize subcriber variables
self
.
_rgb_img
=
None
self
.
_depth_img
=
None
def
init_publishers
(
self
,
timerFreq
:
float
):
# Initialize publishers
# Initialize publishers
self
.
_rgb_detection_publisher
=
self
.
create_publisher
(
Image
,
'rgb_detection'
,
10
)
self
.
_rgb_detection_publisher
=
self
.
create_publisher
(
Image
,
'rgb_detection'
,
10
)
self
.
_mask_detection_publisher
=
self
.
create_publisher
(
Image
,
'mask_detection'
,
10
)
self
.
_mask_detection_publisher
=
self
.
create_publisher
(
Image
,
'mask_detection'
,
10
)
...
@@ -36,21 +37,7 @@ class CameraVision(Node):
...
@@ -36,21 +37,7 @@ class CameraVision(Node):
# Initialize a clock for the publisher
# Initialize a clock for the publisher
self
.
create_timer
(
timerFreq
,
self
.
loop
)
self
.
create_timer
(
timerFreq
,
self
.
loop
)
# Initialize a ROS2 Image to CV2 image converter
self
.
_bridge
=
CvBridge
()
# Callbacks
def
rgb_callback
(
self
,
img
):
print
(
'coucou'
)
self
.
_rgb_img
=
self
.
_bridge
.
imgmsg_to_cv2
(
img
,
desired_encoding
=
'passthrough'
)
def
depth_callback
(
self
,
img
):
width
=
img
.
dim
[
0
]
.
size
height
=
img
.
dim
[
1
]
.
size
self
.
_depth_img
=
np
.
array
(
img
.
data
)
.
reshape
((
width
,
height
))
def
publish_msgs
(
self
,
image
,
mask
):
def
publish_msgs
(
self
,
image
,
mask
):
# Convert cv2 images to ROS2 RGB Image20
# Convert cv2 images to ROS2 RGB Image20
...
@@ -79,12 +66,17 @@ class CameraVision(Node):
...
@@ -79,12 +66,17 @@ class CameraVision(Node):
# Node internal loop
# Node internal loop
def
loop
(
self
):
def
loop
(
self
):
if
self
.
_rgb_img
is
None
:
"""
print
(
'a'
)
Main loop to call
"""
# update images
if
self
.
_update_imgs
()
is
None
:
return
return
color_image
=
np
.
asanyarray
(
self
.
_color_frame
.
get_data
())
# Convert image to HSV for easier thresholding
# Convert image to HSV for easier thresholding
image
=
cv2
.
cvtColor
(
self
.
_rgb_img
,
cv2
.
COLOR_BGR2HSV
)
image
=
cv2
.
cvtColor
(
color_image
,
cv2
.
COLOR_BGR2HSV
)
# Seuillage par colorimétrie
# Seuillage par colorimétrie
mask
=
cv2
.
inRange
(
image
,
self
.
_low
,
self
.
_high
)
mask
=
cv2
.
inRange
(
image
,
self
.
_low
,
self
.
_high
)
...
@@ -114,7 +106,7 @@ class CameraVision(Node):
...
@@ -114,7 +106,7 @@ class CameraVision(Node):
findPt
=
False
findPt
=
False
(
x
,
y
)
=
0
,
0
(
x
,
y
)
=
0
,
0
for
c
in
contours
:
for
c
in
sorted_
contours
:
# Compare our mask with our templates
# Compare our mask with our templates
match
=
cv2
.
matchShapes
(
template_contour
,
c
,
3
,
0.0
)
match
=
cv2
.
matchShapes
(
template_contour
,
c
,
3
,
0.0
)
...
@@ -124,7 +116,7 @@ class CameraVision(Node):
...
@@ -124,7 +116,7 @@ class CameraVision(Node):
(
x
,
y
),
radius
=
cv2
.
minEnclosingCircle
(
c
)
(
x
,
y
),
radius
=
cv2
.
minEnclosingCircle
(
c
)
# If we find a correct match that is big enough, we publish data
# If we find a correct match that is big enough, we publish data
if
min
(
match
,
match2
)
<
0.3
and
radius
>
30
and
y
>
2.0
/
5
*
480
:
if
min
(
match
,
match2
)
<
0.3
and
radius
>
30
:
findPt
=
True
findPt
=
True
break
# Stop checking other contours
break
# Stop checking other contours
...
@@ -139,23 +131,19 @@ class CameraVision(Node):
...
@@ -139,23 +131,19 @@ class CameraVision(Node):
# Publish images and string message
# Publish images and string message
self
.
publish_msgs
(
image
,
mask
)
self
.
publish_msgs
(
image
,
mask
)
# Depth Program
# Depth calculus
if
self
.
_depth_img
is
None
:
x
,
y
=
int
(
x
),
int
(
y
)
return
color_intrin
=
self
.
_color_frame
.
profile
.
as_video_stream_profile
()
.
intrinsics
depth
=
self
.
_depth_img
print
(
depth
[
int
(
y
),
int
(
x
)])
"""
if findPt:
circle_points
=
[]
circle_points
=
[]
D_RADIUS
=
10
D_RADIUS
=
10
for X in range(int(x)-D_RADIUS, int(x)+D_RADIUS):
for
X
in
range
(
x
-
D_RADIUS
,
x
+
D_RADIUS
):
for Y in range(int(y)-D_RADIUS, int(y)+D_RADIUS):
for
Y
in
range
(
y
-
D_RADIUS
,
y
+
D_RADIUS
):
if (X-int(x))**2 + (Y-int(y))**2 <= D_RADIUS:
if
(
X
-
x
)
**
2
+
(
Y
-
y
)
**
2
<=
D_RADIUS
:
circle_points.append(depth[Y, X])
depth
=
self
.
_depth_dist_frame
.
get_distance
(
x
,
y
)
dx
,
dy
,
dz
=
rs
.
rs2_deproject_pixel_to_point
(
color_intrin
,
[
x
,
y
],
depth
)
circle_points
.
append
(
math
.
sqrt
(
dx
**
2
+
dy
**
2
+
dz
**
2
))
#publier moy(circle_points)
#publier moy(circle_points)
print
(
statistics
.
mean
(
circle_points
))
print
(
statistics
.
mean
(
circle_points
))
"""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment