diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c894b51bba4ebf7f5c1062b6bd34f3a339cde90..778b3ade817184f81af9d7de1a458658dd0a0f2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,199 +1,15 @@ cmake_minimum_required(VERSION 2.8.3) -project(ddviz-python) +project(ddviz) -## Compile as C++11, supported in ROS Kinetic and newer -# add_compile_options(-std=c++11) - -## Find catkin macros and libraries -## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) -## is used, also find other catkin packages find_package(catkin REQUIRED COMPONENTS nav_msgs - mccd_msgs rospy ) -## System dependencies are found with CMake's conventions -# find_package(Boost REQUIRED COMPONENTS system) - - -## Uncomment this if the package has a setup.py. This macro ensures -## modules and global scripts declared therein get installed -## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html -# catkin_python_setup() - -################################################ -## Declare ROS messages, services and actions ## -################################################ - -## To declare and build messages, services or actions from within this -## package, follow these steps: -## * Let MSG_DEP_SET be the set of packages whose message types you use in -## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). -## * In the file package.xml: -## * add a build_depend tag for "message_generation" -## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET -## * If MSG_DEP_SET isn't empty the following dependency has been pulled in -## but can be declared for certainty nonetheless: -## * add a exec_depend tag for "message_runtime" -## * In this file (CMakeLists.txt): -## * add "message_generation" and every package in MSG_DEP_SET to -## find_package(catkin REQUIRED COMPONENTS ...) -## * add "message_runtime" and every package in MSG_DEP_SET to -## catkin_package(CATKIN_DEPENDS ...) -## * uncomment the add_*_files sections below as needed -## and list every .msg/.srv/.action file to be processed -## * uncomment the generate_messages entry below -## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) - -## Generate messages in the 'msg' folder -# add_message_files( -# FILES -# Message1.msg -# Message2.msg -# ) - -## Generate services in the 'srv' folder -# add_service_files( -# FILES -# Service1.srv -# Service2.srv -# ) - -## Generate actions in the 'action' folder -# add_action_files( -# FILES -# Action1.action -# Action2.action -# ) - -## Generate added messages and services with any dependencies listed here -# generate_messages( -# DEPENDENCIES -# nav_msgs -# ) - -################################################ -## Declare ROS dynamic reconfigure parameters ## -################################################ - -## To declare and build dynamic reconfigure parameters within this -## package, follow these steps: -## * In the file package.xml: -## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" -## * In this file (CMakeLists.txt): -## * add "dynamic_reconfigure" to -## find_package(catkin REQUIRED COMPONENTS ...) -## * uncomment the "generate_dynamic_reconfigure_options" section below -## and list every .cfg file to be processed - -## Generate dynamic reconfigure parameters in the 'cfg' folder -# generate_dynamic_reconfigure_options( -# cfg/DynReconf1.cfg -# cfg/DynReconf2.cfg -# ) - -################################### -## catkin specific configuration ## -################################### -## The catkin_package macro generates cmake config files for your package -## Declare things to be passed to dependent projects -## INCLUDE_DIRS: uncomment this if your package contains header files -## LIBRARIES: libraries you create in this project that dependent projects also need -## CATKIN_DEPENDS: catkin_packages dependent projects also need -## DEPENDS: system dependencies of this project that dependent projects also need -catkin_package( -# INCLUDE_DIRS include -# LIBRARIES ddviz-python -# CATKIN_DEPENDS nav_msgs rospy -# DEPENDS system_lib -) - -########### -## Build ## -########### +catkin_python_setup() +catkin_package() -## Specify additional locations of header files -## Your package locations should be listed before other locations -include_directories( -# include - ${catkin_INCLUDE_DIRS} +catkin_install_python( + PROGRAMS nodes/ddviz + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) - -## Declare a C++ library -# add_library(${PROJECT_NAME} -# src/${PROJECT_NAME}/ddviz-python.cpp -# ) - -## Add cmake target dependencies of the library -## as an example, code may need to be generated before libraries -## either from message generation or dynamic reconfigure -# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Declare a C++ executable -## With catkin_make all packages are built within a single CMake context -## The recommended prefix ensures that target names across packages don't collide -# add_executable(${PROJECT_NAME}_node src/ddviz-python_node.cpp) - -## Rename C++ executable without prefix -## The above recommended prefix causes long target names, the following renames the -## target back to the shorter version for ease of user use -## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" -# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") - -## Add cmake target dependencies of the executable -## same as for the library above -# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Specify libraries to link a library or executable target against -# target_link_libraries(${PROJECT_NAME}_node -# ${catkin_LIBRARIES} -# ) - -############# -## Install ## -############# - -# all install targets should use catkin DESTINATION variables -# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html - -## Mark executable scripts (Python etc.) for installation -## in contrast to setup.py, you can choose the destination -# install(PROGRAMS -# scripts/my_python_script -# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark executables and/or libraries for installation -# install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node -# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark cpp header files for installation -# install(DIRECTORY include/${PROJECT_NAME}/ -# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -# FILES_MATCHING PATTERN "*.h" -# PATTERN ".svn" EXCLUDE -# ) - -## Mark other files for installation (e.g. launch and bag files, etc.) -# install(FILES -# # myfile1 -# # myfile2 -# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -# ) - -############# -## Testing ## -############# - -## Add gtest based cpp test target and link libraries -# catkin_add_gtest(${PROJECT_NAME}-test test/test_ddviz-python.cpp) -# if(TARGET ${PROJECT_NAME}-test) -# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) -# endif() - -## Add folders to be run by python nosetests -# catkin_add_nosetests(test) diff --git a/README.md b/README.md index e4a79c7e23a738f4edcb4f307f3425b78a490d70..99569a88f036e55879643afe8445e80d242a7dde 100644 --- a/README.md +++ b/README.md @@ -8,5 +8,5 @@ pip3 install --upgrade pyglet ## Launch ``` -rosrun ddviz-python ddviz-python.py +rosrun ddviz ddviz ``` diff --git a/nodes/ddviz b/nodes/ddviz new file mode 100755 index 0000000000000000000000000000000000000000..1e653c7adc4a1303be867f42e2f04d44d998c6fa --- /dev/null +++ b/nodes/ddviz @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +import rospy +from ddviz import run_simulation + +if __name__ == '__main__': + + try: + rospy.init_node("ddviz") + run_simulation() + rospy.spin() + except rospy.ROSInterruptException: + exit(0) \ No newline at end of file diff --git a/package.xml b/package.xml index a3a6694103536eb8a1808769aa788e58948f8e56..5eb6744a53da5722b9a1fd8d2a8baa6ff0bc1b6e 100644 --- a/package.xml +++ b/package.xml @@ -1,68 +1,19 @@ <?xml version="1.0"?> <package format="2"> - <name>ddviz-python</name> - <version>0.0.0</version> - <description>The ddviz-python package</description> + <name>ddviz</name> + <version>1.0.0</version> + <description>2D visualisation of CdF terrain in realtime</description> - <!-- One maintainer tag required, multiple allowed, one person per tag --> - <!-- Example: --> - <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> --> - <maintainer email="thomas@todo.todo">thomas</maintainer> + <maintainer email="charles.javerliat@gmail.com">Charles JAVERLIAT</maintainer> + <maintainer email="thomas.vadebout@insa-lyon.fr">Thomas VADEBOUT</maintainer> + <license>GPLv3</license> - <!-- One license tag required, multiple allowed, one license per tag --> - <!-- Commonly used license strings: --> - <!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 --> - <license>TODO</license> - - - <!-- Url tags are optional, but multiple are allowed, one per tag --> - <!-- Optional attribute type can be: website, bugtracker, or repository --> - <!-- Example: --> - <!-- <url type="website">http://wiki.ros.org/ddviz-python</url> --> - - - <!-- Author tags are optional, multiple are allowed, one per tag --> - <!-- Authors do not have to be maintainers, but could be --> - <!-- Example: --> - <!-- <author email="jane.doe@example.com">Jane Doe</author> --> - - - <!-- The *depend tags are used to specify dependencies --> - <!-- Dependencies can be catkin packages or system dependencies --> - <!-- Examples: --> - <!-- Use depend as a shortcut for packages that are both build and exec dependencies --> - <!-- <depend>roscpp</depend> --> - <!-- Note that this is equivalent to the following: --> - <!-- <build_depend>roscpp</build_depend> --> - <!-- <exec_depend>roscpp</exec_depend> --> - <!-- Use build_depend for packages you need at compile time: --> - <!-- <build_depend>message_generation</build_depend> --> - <!-- Use build_export_depend for packages you need in order to build against this package: --> - <!-- <build_export_depend>message_generation</build_export_depend> --> - <!-- Use buildtool_depend for build tool packages: --> - <!-- <buildtool_depend>catkin</buildtool_depend> --> - <!-- Use exec_depend for packages you need at runtime: --> - <!-- <exec_depend>message_runtime</exec_depend> --> - <!-- Use test_depend for packages you need only for testing: --> - <!-- <test_depend>gtest</test_depend> --> - <!-- Use doc_depend for packages you need only for building documentation: --> - <!-- <doc_depend>doxygen</doc_depend> --> <buildtool_depend>catkin</buildtool_depend> - <build_depend>nav_msgs</build_depend> - <build_depend>mccd_msgs</build_depend> - <build_depend>rospy</build_depend> - <build_export_depend>nav_msgs</build_export_depend> - <build_export_depend>mccd_msgs</build_export_depend> - <build_export_depend>rospy</build_export_depend> + <exec_depend>nav_msgs</exec_depend> <exec_depend>mccd_msgs</exec_depend> <exec_depend>rospy</exec_depend> + <exec_depend>pyglet</exec_depend> - - <!-- The export tag contains other, unspecified, tags --> - <export> - <!-- Other tools can request additional information be placed here --> - - </export> </package> diff --git a/ressources/galere.png b/resources/galere.png similarity index 100% rename from ressources/galere.png rename to resources/galere.png diff --git a/resources/icon.png b/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..902baaef49dc64f2b2e7b708800288c0fe8faf5a Binary files /dev/null and b/resources/icon.png differ diff --git a/resources/sample_0.png b/resources/sample_0.png new file mode 100644 index 0000000000000000000000000000000000000000..182dfd6c0a4ebb55d0ca2437b2a1f74ed617eb72 Binary files /dev/null and b/resources/sample_0.png differ diff --git a/resources/sample_1.png b/resources/sample_1.png new file mode 100644 index 0000000000000000000000000000000000000000..99a8a4ef588d30742bbc0d73a48c0c8f56a14a18 Binary files /dev/null and b/resources/sample_1.png differ diff --git a/resources/sample_2.png b/resources/sample_2.png new file mode 100644 index 0000000000000000000000000000000000000000..9ab08dd247f1bd4e955643747eb64365aa377b34 Binary files /dev/null and b/resources/sample_2.png differ diff --git a/resources/sample_3.png b/resources/sample_3.png new file mode 100644 index 0000000000000000000000000000000000000000..01cb6c30fb16d5f87500ba1ef709845261e9f3f5 Binary files /dev/null and b/resources/sample_3.png differ diff --git a/ressources/terrain.svg b/resources/terrain.svg similarity index 100% rename from ressources/terrain.svg rename to resources/terrain.svg diff --git a/ressources/terrain_high.png b/resources/terrain_high.png similarity index 100% rename from ressources/terrain_high.png rename to resources/terrain_high.png diff --git a/ressources/terrain_low.png b/resources/terrain_low.png similarity index 100% rename from ressources/terrain_low.png rename to resources/terrain_low.png diff --git a/setup.py b/setup.py index 03efc82002174f4148b2b9f0768255511bee958b..15968c6c3d69eb293b02ef981f613e6686f9ca2f 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from catkin_pkg.python_setup import generate_distutils_setup # fetch values from package.xml setup_args = generate_distutils_setup( - packages='ddviz_python'], + packages=['ddviz'], package_dir={'': 'src'}, ) diff --git a/src/DynamicObject.py b/src/DynamicObject.py deleted file mode 100644 index f254e4e72dd6eeeb410bb867bc16f3b8f0b6d7a5..0000000000000000000000000000000000000000 --- a/src/DynamicObject.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -Something that can be viewed on the visualization window -and which can evolve over time (position, rotation, status) -""" - -from pyglet import sprite -from pyglet import image - -class DynamicObject(): - - def __init__(self, sprite_file_dir): - self.sprite_file_dir = sprite_file_dir - - self.x = 0 # x coordinate in mm - self.y = 0 # y coordinate in mm - self.r = 0 # angle in radians - - sprite_img = image.load(sprite_file_dir) - - # set anchor at the middle of the image (useful for sprite pos and rot) - sprite_img.anchor_x = sprite_img.width // 2 - sprite_img.anchor_y = sprite_img.height // 2 - - self.sprite = sprite.Sprite(sprite_img, x=self.x, y=self.y) - - def set_x(self, x): - self.x = x - self.sprite.x = self.x - - def set_y(self, y): - self.y = y - self.sprite.y = self.y - - def set_r(self, r): - self.r = r - self.sprite.rotation = 90 + self.r * 57.2957795 # rad -> deg - print(self.sprite.rotation) - - def __repr__(self): - print("___DynamicObject___") - print("sprite_file_dir : "+self.sprite_file_dir) - diff --git a/src/LaGalere.py b/src/LaGalere.py deleted file mode 100644 index f6fa3bae0e9808882b1603b1de4c54fb2357d071..0000000000000000000000000000000000000000 --- a/src/LaGalere.py +++ /dev/null @@ -1,11 +0,0 @@ - -from Robot import Robot -import globals -import os - -sprite_file_dir = os.path.join(globals.RESOURES_DIR, "galere.png") - - -class LaGalere(Robot): - def __init__(self): - Robot.__init__(self, sprite_file_dir) diff --git a/src/Robot.py b/src/Robot.py deleted file mode 100644 index e2c710eb0eafc42ba230a5725b55bed9becb956d..0000000000000000000000000000000000000000 --- a/src/Robot.py +++ /dev/null @@ -1,7 +0,0 @@ - -from DynamicObject import DynamicObject - -class Robot(DynamicObject): - - def __init__(self, sprite_file_dir): - DynamicObject.__init__(self, sprite_file_dir) diff --git a/src/VisualizationCore.py b/src/VisualizationCore.py deleted file mode 100644 index e4a26d535fc426b6fb1696a639bccf653b9e970f..0000000000000000000000000000000000000000 --- a/src/VisualizationCore.py +++ /dev/null @@ -1,53 +0,0 @@ - -import pyglet -from pyglet import image -from pyglet import gl -import globals -import os - -winWidth = 1500 -winHeight = 1000 - -dynamicObjecsList = [] - - -def loadBackground(): - return image.load(os.path.join(globals.RESOURES_DIR, "terrain_high.png")) - - -def update(up): - pass - - -def initVisualization(): - # allow use of an extra sample buffer (antialiasing) - config = pyglet.gl.Config(sample_buffers=1, samples=4) - window = pyglet.window.Window( - config=config, width=winWidth, height=winHeight, resizable=False) - bg = loadBackground() - - # scale to fit well terrain - x_scaling = winWidth/bg.width - y_scaling = winHeight/bg.height - gl.glScalef(x_scaling, y_scaling, 1) - print("window launched with scaling " + str((x_scaling, y_scaling))) - - @window.event - def on_draw(): - window.clear() - bg.blit(0, 0, 0) - - for dynObj in dynamicObjecsList: - dynObj.sprite.draw() - - @window.event - def on_close(): - exit(0) - - # enter in event loop until window is closed -> blocking - pyglet.clock.schedule_interval(update, 1/10) - pyglet.app.run() - - -def addDynamicObject(dynObj): - dynamicObjecsList.append(dynObj) diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/board.py b/src/board.py new file mode 100644 index 0000000000000000000000000000000000000000..6a318a7cb87965cbd0a13f36e701269df1952c74 --- /dev/null +++ b/src/board.py @@ -0,0 +1,75 @@ +from utils import load_sprite, ppm +from math import pi, sin, degrees +from robot import Robot +from sample import SampleType, Sample + +sample_test = Sample(SampleType.RED) + + +class Board: + + def __init__(self, texture_path, width, height): + self._bg_sprite = load_sprite(texture_path, width * ppm, height * ppm) + self._width = width + self._height = height + self._robot = Robot() + self._samples = list() + + def init_board(self): + # Robot starts in the camp + self._robot.x = self._robot.height / 2 + 0.03 + self._robot.y = self._robot.width / 2 + 1.05 + self._robot.theta = 90 + + # Create samples + self._samples.clear() + + sample1 = Sample(SampleType.RED) + sample1.x = 0.85 + sample1.y = 0.45 + sample1.theta = 56 + + sample2 = Sample(SampleType.GREEN) + sample2.x = 0.72 + sample2.y = 0.55 + sample2.theta = 24 + + sample3 = Sample(SampleType.BLUE) + sample3.x = 0.9 + sample3.y = 0.6 + sample3.theta = 12 + + sample4 = Sample(SampleType.ROCKS) + sample4.x = 1.0 + sample4.y = 0.45 + sample4.theta = -87 + + self._samples.extend([sample1, sample2, sample3, sample4]) + + def draw(self): + self._bg_sprite.draw() + + # Draw samples on the board + for sample in self._samples: + sample.draw() + + # TODO: dessiner l'abris de chantier + + # TODO: dessiner la vitrine + + # TODO: dessiner la statuette + + + # dessiner le robot + self._robot.draw() + + def update(self, dt): + self._robot.update(dt) + + @property + def width(self): + return self._width + + @property + def height(self): + return self._height \ No newline at end of file diff --git a/src/ddviz-python.py b/src/ddviz-python.py deleted file mode 100755 index 2fad949f92ff398744233f2d807714773099f2ff..0000000000000000000000000000000000000000 --- a/src/ddviz-python.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python3 - -from LaGalere import LaGalere -import VisualizationCore - -import rospy -from mccd_msgs.msg import Odometry - - -class DdvizNode: - - def odomCallback(self, odom): - self.pos_x = odom.x - self.pos_y = odom.y - self.rot = odom.theta - self.updateVisualization() - - def __init__(self): - self.galere = LaGalere() - - self.odomSubscriber = rospy.Subscriber( - "/mccd/odom", Odometry, self.odomCallback) - self.initVisualization() - - rospy.spin() - - def initVisualization(self): - self.galere.set_x(1500) - self.galere.set_y(1000) - self.galere.set_r(3*1.57) - VisualizationCore.addDynamicObject(self.galere) - VisualizationCore.initVisualization() - - def updateVisualization(self): - self.galere.set_x(self.pos_x*1000) - self.galere.set_y(self.pos_y*1000) - self.galere.set_r(-self.rot) - - -if __name__ == '__main__': - - rospy.init_node("ddviz") - - try: - DdvizNode() - except rospy.ROSInterruptException: - pass diff --git a/src/ddviz.py b/src/ddviz.py new file mode 100755 index 0000000000000000000000000000000000000000..be09e9eb26b6f9cf35cdaefcbcf2d9e2c27a033f --- /dev/null +++ b/src/ddviz.py @@ -0,0 +1,44 @@ +from pyglet import gl, window, clock, app +from board import Board +from utils import ppm, load_img + +# Terrain dimensions (in meters) +board_width = 3 +board_height = 2 + +window_width = 1500 +window_height = 930 + +max_fps = 60 + +window = window.Window(caption="ddviz", config=gl.Config(), width=window_width, height=window_height, resizable=True) +window.set_icon(load_img("icon.png")) +window.maximize() + +board = Board("terrain_high.png", board_width, board_height) +board.init_board() + +def update(dt): + board.update(dt) + +@window.event +def on_draw(): + gl.glClearColor(0.92, 0.94, 0.94, 1.0) + window.clear() + + # Center everything and render the whole board + gl.glPushMatrix() + gl.glTranslatef((window.width - board_width * ppm) / 2, (window.height - board_height * ppm) / 2, 0) + board.draw() + + # TODO: draw estimated score, speed, ... + + gl.glPopMatrix() + +@window.event +def on_close(): + exit(0) + +def run_simulation(): + clock.schedule_interval(update, 1 / max_fps) + app.run() \ No newline at end of file diff --git a/src/entity.py b/src/entity.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c1298a747371d69a7924b523aed35e2e4d54ce --- /dev/null +++ b/src/entity.py @@ -0,0 +1,57 @@ +from utils import load_sprite, ppm + +class Entity: + + def __init__(self, texture_path, width, height): + self._sprite = load_sprite(texture_path, width * ppm, height * ppm) + self._sprite.image.anchor_x = self._sprite.image.width // 2 + self._sprite.image.anchor_y = self._sprite.image.height // 2 + self._sprite.x = 0 + self._sprite.y = 0 + self._sprite.rotation = 0 + self._x = 0 + self._y = 0 + self._theta = 0 + self._width = width + self._height = height + + def draw(self): + self._sprite.draw() + + def update(self, dt): + pass + + @property + def width(self): + return self._width + + @property + def height(self): + return self._height + + @property + def x(self): + return self._x + + @x.setter + def x(self, x): + self._x = x + self._sprite.x = x * ppm + + @property + def y(self): + return self._y + + @y.setter + def y(self, y): + self._y = y + self._sprite.y = y * ppm + + @property + def theta(self): + return self._theta + + @theta.setter + def theta(self, theta): + self._theta = theta + self._sprite.rotation = theta \ No newline at end of file diff --git a/src/globals.py b/src/globals.py index d5880392e3a5dfba8f10e9252b9f657489bc6433..e77d0b1715a1166a6ad436a240021187c0f8146c 100644 --- a/src/globals.py +++ b/src/globals.py @@ -3,4 +3,4 @@ import os from posixpath import dirname ROOT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir) -RESOURES_DIR = os.path.join(ROOT_DIR, "ressources") +RESOURES_DIR = os.path.join(ROOT_DIR, "resources") diff --git a/src/robot.py b/src/robot.py new file mode 100644 index 0000000000000000000000000000000000000000..fef39746ad75ef3101e97b202ee5ed80a1816bc4 --- /dev/null +++ b/src/robot.py @@ -0,0 +1,18 @@ +from entity import Entity +from math import degrees +import rospy +from mccd_msgs.msg import Odometry + +class Robot(Entity): + + def __init__(self): + super().__init__("galere.png", 0.348, 0.281) + self._odom_sub = rospy.Subscriber("/mccd/odom", Odometry, self.odometry_cb) + + def update(self, dt): + pass + + def odometry_cb(self, odom): + self.x = odom.x + self.y = odom.y + self.theta = degrees(odom.theta) \ No newline at end of file diff --git a/src/sample.py b/src/sample.py new file mode 100644 index 0000000000000000000000000000000000000000..8c9b35c88dfa15bb2062f8bb5a2bb7c7e8fdab81 --- /dev/null +++ b/src/sample.py @@ -0,0 +1,20 @@ +from entity import Entity +from enum import IntEnum + +class SampleType(IntEnum): + ROCKS = 0 + RED = 1 + GREEN = 2 + BLUE = 3 + +class Sample(Entity): + + def __init__(self, type): + super().__init__("sample_" + str(int(type)) + ".png", 0.13, 0.15) + + def update(self, dt): + pass + + def draw(self): + super().draw() + # TODO: take into account flipped samples (render them differently ?) \ No newline at end of file diff --git a/src/utils.py b/src/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..7deaefdf4a7c7dd53442bf77c5ad85a0e1f07b3d --- /dev/null +++ b/src/utils.py @@ -0,0 +1,14 @@ +import os +import globals +from pyglet import image, sprite + +ppm = 400 # pixels per meter, used to convert from world to screen coords + +def load_img(img_name): + return image.load(os.path.join(globals.RESOURES_DIR, img_name)) + +def load_sprite(img_name, width, height): + s = sprite.Sprite(load_img(img_name)) + s.scale_x = width / s.image.width + s.scale_y = height / s.image.height + return s \ No newline at end of file