Skip to content

Commit b0fe052

Browse files
jebkingTimothy Tamm
authored and
Timothy Tamm
committed
Camera (#18)
Add camera sensor and display modules
1 parent 47592ba commit b0fe052

9 files changed

+180
-10
lines changed

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
Code for The Harvard Undergraduate Robotics Club's MATE ROV team.
44

5-
The code consist of separate modules that are run on either the ROV or on a ground base. Inter-module communications are orchestrated by the Server (server.py). Modules send messages to the server and subscribe to certain message types. When the server receives a message of a certain type, it forwards it to all the modules that have subscribed to that message type.
5+
The code consist of separate modules that are run on either the ROV or on a ground base. Inter-module communications are orchestrated by the Server (`server.py`). Modules send messages to the server and subscribe to certain message types. When the server receives a message of a certain type, it forwards it to all the modules that have subscribed to that message type.
66

77
## How to run
88

9-
1. Execute ./server.py
9+
1. Execute `./server.py`
1010
2. Execute all of your modules
1111

1212
## Adding new modules
@@ -26,10 +26,10 @@ The code consist of separate modules that are run on either the ROV or on a grou
2626
protoc -I=./ --python_out=./ ./second.proto
2727
```
2828
- Run the make command in the comm folder.
29-
- In messages/__init__.py do the following:
29+
- In `messages/__init__.py` do the following:
3030
- Import your new compiled buffer.
3131
- Add a message type enum for your new buffer.
32-
- Add the new message type and the associated buffer to message_buffers.
32+
- Add the new message type and the associated buffer to `message_buffers`.
3333
- Example:
3434
- Before:
3535
```
@@ -58,4 +58,4 @@ The code consist of separate modules that are run on either the ROV or on a grou
5858
MsgType.SECOND: SecondMsg
5959
}
6060
```
61-
2. Make a new module class that inherits from robomodules.ProtoModule. Look at MockGuiModule.py and MockSensorModule for examples on modules
61+
2. Make a new module class that inherits from `robomodules.ProtoModule`. Look at `MockGuiModule.py` and `MockSensorModule` for examples on modules.

cameraDisplayModule.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import cv2
5+
import robomodules as rm
6+
from messages import message_buffers, MsgType
7+
import pickle
8+
9+
ADDRESS = os.environ.get("BIND_ADDRESS","localhost")
10+
PORT = os.environ.get("BIND_PORT", 11297)
11+
12+
FREQUENCY = 0
13+
14+
class CameraDisplayModule(rm.ProtoModule):
15+
def __init__(self, addr, port):
16+
self.subscriptions = [MsgType.CAMERA_FRAME_MSG]
17+
super().__init__(addr, port, message_buffers, MsgType, FREQUENCY, self.subscriptions)
18+
self.frame = None
19+
20+
def msg_received(self, msg, msg_type):
21+
# This gets called whenever any message is received
22+
# We receive pickled frames here.
23+
if msg_type == MsgType.CAMERA_FRAME_MSG:
24+
self.frame = msg.cameraFrame
25+
self._display_serialized_image()
26+
27+
28+
def tick(self):
29+
# this function will get called in a loop with FREQUENCY frequency
30+
# process the serialized frame
31+
return
32+
33+
def _display_serialized_image(self):
34+
if self.frame == None:
35+
print('frame == None')
36+
return
37+
frame = pickle.loads(self.frame)
38+
# Our operations on the frame come here
39+
# frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
40+
# Display the resulting frame
41+
cv2.imshow('frame', frame)
42+
if cv2.waitKey(1) & 0xFF == ord('q'):
43+
return
44+
45+
def main():
46+
module = CameraDisplayModule(ADDRESS, PORT)
47+
module.run()
48+
49+
if __name__ == "__main__":
50+
main()

cameraSensorModule.py

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env python3
2+
3+
import os, random
4+
import robomodules as rm
5+
from messages import *
6+
import numpy as np
7+
import cv2
8+
import pickle
9+
10+
ADDRESS = os.environ.get("BIND_ADDRESS","localhost")
11+
PORT = os.environ.get("BIND_PORT", 11297)
12+
13+
FREQUENCY = 30
14+
15+
class CameraSensorModule(rm.ProtoModule):
16+
def __init__(self, addr, port, camera_port):
17+
super().__init__(addr, port, message_buffers, MsgType, FREQUENCY)
18+
self.cam = cv2.VideoCapture(camera_port)
19+
20+
def msg_received(self, msg, msg_type):
21+
# This gets called whenever any message is received
22+
# This module only sends data, so we ignore incoming messages
23+
return
24+
25+
def tick(self):
26+
# this function will get called in a loop with FREQUENCY frequency
27+
# gets the camera feed, puts it into the message
28+
msg = CameraFrameMsg()
29+
ret, frame = self.cam.read()
30+
msg.cameraFrame = pickle.dumps(frame)
31+
msg = msg.SerializeToString()
32+
self.write(msg, MsgType.CAMERA_FRAME_MSG)
33+
34+
def main():
35+
module = CameraSensorModule(ADDRESS, PORT, 0)
36+
module.run()
37+
38+
if __name__ == "__main__":
39+
main()

messages/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
protobuf: mockMsg.proto
1+
protobuf: mockMsg.proto cameraFrameMsg.proto
22
protoc -I=./ --python_out=./ ./mockMsg.proto
3+
protoc -I=./ --python_out=./ ./cameraFrameMsg.proto

messages/__init__.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
from enum import Enum
22
from .mockMsg_pb2 import MockMsg
3+
from .cameraFrameMsg_pb2 import CameraFrameMsg
34

45
class MsgType(Enum):
56
MOCK_MSG = 0
7+
CAMERA_FRAME_MSG = 1
68

79
message_buffers = {
8-
MsgType.MOCK_MSG: MockMsg
10+
MsgType.MOCK_MSG: MockMsg,
11+
MsgType.CAMERA_FRAME_MSG: CameraFrameMsg
912
}
1013

1114

12-
__all__ = ['MsgType', 'message_buffers', 'MockMsg']
15+
__all__ = ['MsgType', 'message_buffers', 'MockMsg', 'CameraFrameMsg']

messages/cameraFrameMsg.proto

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
syntax = "proto2";
2+
3+
package mateROV;
4+
5+
message CameraFrameMsg {
6+
7+
required bytes cameraFrame = 1;
8+
}

messages/cameraFrameMsg_pb2.py

+69
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

messages/mockMsg_pb2.py

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)