Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature rapid neem creation #216

Open
wants to merge 49 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
8d0d50d
Adds the initial conceptual idea, which seems to be working
Leusmann Aug 16, 2024
fce61af
Adds first ProcThor environment
Leusmann Aug 16, 2024
2f113ff
Kind of working demo
Leusmann Aug 20, 2024
e523797
Stop ignoring the Giskard answer when spawning the mesh
Leusmann Aug 20, 2024
93e1cad
Merge branch 'feature/rapid-neem-creation' into HEAD
Leusmann Aug 20, 2024
15666ba
Adds file// to the replaced key words
Leusmann Aug 20, 2024
c144628
Adds the functionallty to create NEEMs of the task executed.
Leusmann Aug 29, 2024
2c9ad5b
Adds first Multivers experiment
Leusmann Aug 29, 2024
6d126f7
Quick fix to store the object pose at this moment and not the object …
Leusmann Aug 29, 2024
d81e87f
Quick and dirty fix for object poses of believed object. Shouldn't be…
Leusmann Aug 29, 2024
e1b7abd
Changes camera starting postion
Leusmann Aug 29, 2024
9c91788
Adds the Micheal function and the second version
Leusmann Sep 16, 2024
3139a6b
Changes from script so function and adds a second version where the e…
Leusmann Sep 16, 2024
38e1910
Adds the download helper functions. Maybe need to check the paths etc
Leusmann Sep 16, 2024
568cd18
Quick fix for equality. Apparently pybullet creates ids in such a way…
Leusmann Sep 17, 2024
8e62e9c
Merge remote-tracking branch 'origin/dev' into feature-rapid-neem-cre…
Leusmann Oct 4, 2024
7d1feb7
small change to refelct the changes in the Enum
Leusmann Oct 18, 2024
3d737ae
Merge remote-tracking branch 'origin/dev' into feature-rapid-neem-cre…
Leusmann Oct 18, 2024
62af001
Move from functions to class
Leusmann Oct 29, 2024
ea85ba6
Changed from functions to class and simplyfies the download
Leusmann Oct 29, 2024
e2b43e1
Delete house_2
Leusmann Oct 29, 2024
5ebd4e6
Adds documentation strings etc
Leusmann Nov 7, 2024
3518551
Removed unnecessary imports and switched to pycramros lib instead of …
Leusmann Nov 7, 2024
37e2c4a
Changes requester to procthor interface and store it at the proper place
Leusmann Nov 7, 2024
71a469f
Refelct the changes from moving 'requester' to 'external_interface/pr…
Leusmann Nov 7, 2024
0a6db3a
Deleted old version of function and some other stuff
Leusmann Nov 8, 2024
23134bd
Adds the first iteration of the procthor interface example
Leusmann Nov 8, 2024
1c9190d
Refactor function name
Leusmann Nov 20, 2024
cd3bf47
Removes unnecessary comments and refactors function name
Leusmann Nov 20, 2024
700b7a3
Removes old iteration, which somehow made it this far
Leusmann Nov 20, 2024
6a056a5
Removes old iteration, which somehow made it this far
Leusmann Nov 20, 2024
39537b9
Renames CEO in to demo
Leusmann Nov 20, 2024
87e3a98
First iteration of the experiment Interface
Leusmann Nov 27, 2024
200eb14
Changes prints to log messages
Leusmann Dec 4, 2024
f095935
First draft of the PyCRAMGym class
Leusmann Dec 4, 2024
bf5a530
Delete unnecessary files again
Leusmann Dec 4, 2024
b26e94c
Adds the tests for the procthor interface
Leusmann Dec 5, 2024
fa38542
Merge branch 'dev' of github.com:cram2/pycram into feature-rapid-neem…
Leusmann Dec 5, 2024
123d14c
Change function name and remove prints
Leusmann Dec 5, 2024
35593c8
Changes print to log
Leusmann Dec 9, 2024
242ae86
Updates the example to properly log instead of print and use the newe…
Leusmann Dec 9, 2024
924f9e1
Adds the example code for testig purposes
Leusmann Dec 9, 2024
bf2c1a4
Moves example code to the proper file and import that one
Leusmann Dec 9, 2024
a7f7113
Merge remote-tracking branch 'origin/dev' into feature-rapid-neem-cre…
Leusmann Dec 10, 2024
e2725ee
Switches from Enum to pyCRAP
Leusmann Dec 10, 2024
cb46fc6
Changes imports to be realtive
Leusmann Dec 11, 2024
3cff20c
Changes from ObjectTypes to PyCRAP and adds some documentation
Leusmann Dec 11, 2024
f518323
Adds gymnasium to the requirements
Leusmann Dec 11, 2024
00105e5
Restes the camera back to its default position
Leusmann Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions demos/playfield/task_tree_publisher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from pycram.ros import ros_tools
from pycram.designators.action_designator import MoveTorsoActionPerformable, PickUpActionPerformable, \
NavigateActionPerformable
from pycram.datastructures.pose import Pose
from pycram.datastructures.enums import Arms, Grasp, GripperState, WorldMode, ObjectType
from pycram.world_concepts.world_object import Object
from pycram.process_module import simulated_robot
import pycram.tasktree
from pycram.tasktree import with_tree
import pycram.failures
from pycram.designators import object_designator, action_designator
from anytree import RenderTree
from pycram.robot_description import RobotDescription,RobotDescriptionManager

from pycram.worlds.bullet_world import BulletWorld


rdm = RobotDescriptionManager()
rdm.load_description("pr2")
world = BulletWorld(WorldMode.GUI)
robot_obj = Object(RobotDescription.current_robot_description.name, ObjectType.ROBOT, RobotDescription.current_robot_description.name+".urdf", pose=Pose([1, 2, 0]))
milk_obj = Object("milk", ObjectType.MILK,"milk.stl",pose=Pose([1.3, 1, 0.9]))
@with_tree
def plan():
object_description = object_designator.ObjectDesignatorDescription(names=["milk"])
description = action_designator.PlaceAction(object_description, [Pose([1.3, 1, 0.9], [0, 0, 0, 1])], [Arms.LEFT])
with simulated_robot:
NavigateActionPerformable(Pose([0.6, 0.4, 0], [0, 0, 0, 1])).perform()
MoveTorsoActionPerformable(0.3).perform()
PickUpActionPerformable(object_description.resolve(), Arms.LEFT, Grasp.FRONT).perform()
description.resolve().perform()


plan()
tt = pycram.tasktree.task_tree.root

print(RenderTree(tt))

97 changes: 97 additions & 0 deletions demos/pycram_procthor_demo/demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import rospy

from pycram.worlds.bullet_world import BulletWorld
from pycram.datastructures.enums import ObjectType, WorldMode
from pycram.world_concepts.world_object import Object
from pycram.datastructures.pose import Pose

from pycram.datastructures.dataclasses import Color
from demos.playfield.sandcastle import generic_plan
from pycram import World
from pycram.failures import PlanFailure
from pycram.tasktree import task_tree

import traceback
import sqlalchemy
import pycram.orm.base
from pycram.external_interfaces.procthor import ProcThorInterface

engine = sqlalchemy.create_engine("sqlite+pysqlite:///:memory:", echo=False)
session_maker = sqlalchemy.orm.sessionmaker(bind=engine)
session = session_maker()
# ToDo: Many Plans missing, but this needs function pointers and I am not comfortable with it
# plans=[]
robots = []
robot_name = "pr2.urdf"
robots.append(robot_name)
pycram.orm.base.Base.metadata.create_all(engine)
session.commit()
# Set up for ProcThor stuff Example usage
procThorInterface = ProcThorInterface(base_url="http://procthor.informatik.uni-bremen.de:5000/")
number_of_test_environment = 5

# Get Environments
number_of_known_environment = len(
procThorInterface.get_all_environments_stored_below_directory(procThorInterface.source_folder))
print("Number of known Environments:{}".format(number_of_known_environment))
print("Number of needed Testenvironments:{}".format(number_of_test_environment))

if number_of_known_environment < number_of_test_environment:
print("Downloading missing environments...")
procThorInterface.download_num_random_environment(number_of_test_environment - number_of_known_environment)

def runWorld():
counter = 0
works = 0
fails = 0
known_environments = procThorInterface.get_all_environments_stored_below_directory(procThorInterface.source_folder)
world = BulletWorld(WorldMode.GUI)
apartment = None
milk_pos = Pose([1, -1.78, 0.55], [1, 0, 0, 0])
milk = Object("milk", ObjectType.MILK, "milk.stl", pose=Pose([1, -1.78, 0.55], [1, 0, 0, 0]),
color=Color(1, 0, 0, 1))
for robot in robots:
robot_obj = Object("pr2", ObjectType.ROBOT, robot, pose=Pose([1, 2, 0]))
for environment in known_environments:
counter += 1
print("Trying plan: {} with robot: {} in: {}".format("param_plan", robot, environment["name"]))
try:
apartment = Object(environment["name"], ObjectType.ENVIRONMENT, environment["storage_place"])
generic_plan(world)
works += 1
print("Successfully!\n Overall successful tries: {}".format(works))

except PlanFailure as e:
traceback.print_exc()
fails += 1
print("Plan Fail!\n Overall failed tries: {}".format(fails))

except FileNotFoundError as e2:
traceback.print_exc()
fails += 1
print("Fail!\n Overall failed tries: {}".format(fails))

finally:
try:
process_meta_data = pycram.orm.base.ProcessMetaData()
process_meta_data.description = "CEO Test run number {} robot:{} enviroment:{}".format(counter,
robot,
environment)
process_meta_data.insert(session)
task_tree.root.insert(session)
except Exception as e:
traceback.print_exc()
print("Error while storing the NEEM. This should not happen.")
task_tree.reset_tree()
if World.current_world is not None and apartment is not None:
world.remove_object(apartment)
milk.set_pose(milk_pos)
print("reseting world")
if World.current_world is None:
world.remove_object(robot_obj)

print("Resume:\nOverall successful tries: {}\nOverall failed tries: {}".format(works, fails))
World.current_world.exit()


runWorld()
121 changes: 121 additions & 0 deletions examples/interface_examples/procthor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Procthor Interface - Creating a CEO for testing multible robots in mutliple enviromnents
Leusmann marked this conversation as resolved.
Show resolved Hide resolved

This Notebook aims to provide an overview of the ProcThor Interface, by giving an easy-to-understand example on how to
use it. We will be executing a simple pick and place plan with hard coded values and store the NEEMs of these
experiments within a local memory database.

Please be aware that this Notebook (currently) works only when you are connected to the network at the university in
Bremen, otherwise we will not be able to connect to the REST service and the webserver itself.
Leusmann marked this conversation as resolved.
Show resolved Hide resolved

If you want to check if you are able to run the Notebook simply try to ping the following server.

```batch

ping procthor.informatik.uni-bremen.de

```

If you get a positive answer back from the server everything seems to be all right.

Now we need to set up the local memory database.
```python
import sqlalchemy
import pycram.orm.base

engine = sqlalchemy.create_engine("sqlite+pysqlite:///:memory:", echo=False)
session_maker = sqlalchemy.orm.sessionmaker(bind=engine)
session = session_maker()
pycram.orm.base.Base.metadata.create_all(engine)
session.commit()
```
Time for some more setup, while we can technically use multiple robots in the different environments we for now stick
with only PR2. Afterwards, we will start to set up our ProcThorInterface. Our example will work with 5 different
environments.
```python
from pycram.external_interfaces.procthor import ProcThorInterface
from pycram.ros import ros_tools
pycram_path=ros_tools.get_ros_package_path('pycram')

robots =[]
robot_name="pr2.urdf"
robots.append(robot_name)


procthor_rest_endpoint = "http://procthor.informatik.uni-bremen.de:5000/"
source_folder = pycram_path + "resources/tmp/"
procThorInterface=ProcThorInterface(base_url=procthor_rest_endpoint,source_folder=source_folder)
number_of_test_environment=5
```
First let us check how many different environments are already known.

```python
number_of_known_environment = len(
procThorInterface.get_all_environments_stored_below_directory(procThorInterface.source_folder))
print("Number of known Environments:{}".format(number_of_known_environment))
print("Number of needed Testenvironments:{}".format(number_of_test_environment))
```

Now depending on if we have to get some more, we will download some additional:
```python
if number_of_known_environment < number_of_test_environment:
print("Downloading missing environments...")
procThorInterface.download_num_random_environment(number_of_test_environment-number_of_known_environment)
```

Now that the preparations are met we can start to run our plan for each robot (even though it is only one) and each
environment we know:

```python
v = 0
works = 0
fails = 0
known_environments = procThorInterface.get_all_environments_stored_below_directory(procThorInterface.source_folder)
world = BulletWorld(WorldMode.GUI)
apartment = None
milk_pos = Pose([1, -1.78, 0.55], [1, 0, 0, 0])
milk = Object("milk", ObjectType.MILK, "milk.stl", pose=Pose([1, -1.78, 0.55], [1, 0, 0, 0]),
color=Color(1, 0, 0, 1))
for robot in robots:
robot_obj = Object("pr2", ObjectType.ROBOT, robot, pose=Pose([1, 2, 0]))
for environment in known_environments:
v += 1
print("Trying plan: {} with robot: {} in: {}".format("param_plan", robot, environment["name"]))
try:
apartment = Object(environment["name"], ObjectType.ENVIRONMENT, environment["storage_place"])
generic_plan(world)
works += 1
print("Successfully!\n Overall successful tries: {}".format(works))

except PlanFailure as e:
traceback.print_exc()
fails += 1
print("Plan Fail!\n Overall failed tries: {}".format(fails))

except FileNotFoundError as e2:
traceback.print_exc()
fails += 1
print("Fail!\n Overall failed tries: {}".format(fails))

finally:
try:
process_meta_data = pycram.orm.base.ProcessMetaData()
process_meta_data.description = "CEO Test run number {} robot:{} enviroment:{}".format(v, robot,
environment)
process_meta_data.insert(session)
task_tree.root.insert(session)
except Exception as e:
traceback.print_exc()
print("Error while storing the NEEM. This should not happen.")
task_tree.reset_tree()
if World.current_world is not None and apartment is not None:
world.remove_object(apartment)
milk.set_pose(milk_pos)
print("reseting world")
if World.current_world is None:
world.remove_object(robot_obj)

print("Resume:\nOverall successful tries: {}\nOverall failed tries: {}".format(works, fails))
World.current_world.exit()
```


2 changes: 2 additions & 0 deletions src/pycram/designators/action_designator.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,8 @@ class DetectActionPerformable(ActionAbstract):
"""
orm_class: Type[ActionAbstract] = field(init=False, default=ORMDetectAction)

object_at_execution: Optional[ObjectDesignatorDescription.Object] = field(init=False)

@with_tree
def plan(self) -> None:
return DetectingMotion(technique=self.technique,state=self.state, object_designator_description=self.object_designator_description,
Expand Down
3 changes: 2 additions & 1 deletion src/pycram/external_interfaces/giskard.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ def spawn_object(object: Object) -> None:
filename = geometry.file_name
spawn_mesh(object.name, filename, object.get_pose())
else:
spawn_urdf(object.name, object.path, object.get_pose())
ww = spawn_urdf(object.name, object.path, object.get_pose())
print("GiskardSpawnURDF Return value: {} ObjectName:{}".format(ww,object.name))
Leusmann marked this conversation as resolved.
Show resolved Hide resolved


@init_giskard_interface
Expand Down
Loading