diff --git a/free_gait_action_loader/CHANGELOG.rst b/free_gait_action_loader/CHANGELOG.rst
new file mode 100644
index 0000000..3caf8cc
--- /dev/null
+++ b/free_gait_action_loader/CHANGELOG.rst
@@ -0,0 +1,11 @@
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Changelog for package free_gait_action_loader
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Forthcoming
+-----------
+
+0.1.1 (2017-01-31)
+------------------
+* Initial release.
+* Contributors: Peter Fankhauser, Marko Bjelonic, Remo Diethelm
diff --git a/free_gait_action_loader/CMakeLists.txt b/free_gait_action_loader/CMakeLists.txt
new file mode 100644
index 0000000..8a77ab5
--- /dev/null
+++ b/free_gait_action_loader/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Project configuration
+cmake_minimum_required (VERSION 2.8)
+project(free_gait_action_loader)
+
+## 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
+ rospy
+ free_gait_python
+ free_gait_msgs
+)
+
+catkin_package(
+ #INCLUDE_DIRS
+ #LIBRARIES
+ #CATKIN_DEPENDS
+ #DEPENDS
+)
+
+## 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()
+
+#############
+## 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
+catkin_install_python(PROGRAMS
+ bin/free_gait_action_loader/action_loader.py
+ DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
+)
diff --git a/free_gait_action_loader/actions/test.yaml b/free_gait_action_loader/actions/test.yaml
new file mode 100644
index 0000000..8289fd8
--- /dev/null
+++ b/free_gait_action_loader/actions/test.yaml
@@ -0,0 +1,3 @@
+steps:
+ - step:
+ - base_auto:
diff --git a/free_gait_action_loader/bin/free_gait_action_loader/action_loader.py b/free_gait_action_loader/bin/free_gait_action_loader/action_loader.py
new file mode 100755
index 0000000..79d0d33
--- /dev/null
+++ b/free_gait_action_loader/bin/free_gait_action_loader/action_loader.py
@@ -0,0 +1,243 @@
+#! /usr/bin/env python
+
+import roslib
+roslib.load_manifest('free_gait_action_loader')
+from free_gait_action_loader import *
+from free_gait import *
+import rospy
+import actionlib
+import free_gait_msgs.msg
+import free_gait_msgs.srv
+import std_srvs.srv
+import traceback
+from actionlib_msgs.msg import *
+import thread
+
+class ActionLoader:
+
+ def __init__(self):
+ self.name = rospy.get_name()[1:]
+ self.action_list = ActionList(self.name)
+ self.action_list.update()
+ self.collection_list = CollectionList(self.name)
+ self.collection_list.update()
+ self.action_sequence_queue = []
+ self.action = None
+ # Reference to the action client or preview publisher.
+ self.execute_steps_relay = None
+
+ step_action_server_topic = rospy.get_param('/free_gait/action_server')
+ self.execute_steps_client = actionlib.SimpleActionClient(step_action_server_topic, free_gait_msgs.msg.ExecuteStepsAction)
+
+ self.execute_action_server = actionlib.SimpleActionServer("~execute_action", free_gait_msgs.msg.ExecuteActionAction, \
+ execute_cb=self._execute_action_callback, auto_start = False)
+ self.execute_action_server.register_preempt_callback(self.preempt)
+ self.execute_action_server.start()
+
+ step_preview_topic = rospy.get_param('/free_gait/preview_topic')
+ self.preview_publisher = rospy.Publisher(step_preview_topic, free_gait_msgs.msg.ExecuteStepsActionGoal, queue_size=1)
+
+ rospy.Service('~update', std_srvs.srv.Trigger, self.update)
+ rospy.Service('~list_actions', free_gait_msgs.srv.GetActions, self.list_actions)
+ rospy.Service('~list_collections', free_gait_msgs.srv.GetCollections, self.list_collections)
+ rospy.Service('~send_action', free_gait_msgs.srv.SendAction, self._send_action_callback)
+ rospy.Service('~preview_action', free_gait_msgs.srv.SendAction, self._preview_action_callback)
+ rospy.Service('~send_action_sequence', free_gait_msgs.srv.SendActionSequence, self._send_action_sequence_callback)
+ rospy.on_shutdown(self.preempt)
+
+ def update(self, request):
+ success = self.action_list.update() and self.collection_list.update()
+ response = std_srvs.srv.TriggerResponse()
+ response.success = success
+ return response
+
+ def list_actions(self, request):
+ response = free_gait_msgs.srv.GetActionsResponse()
+ action_ids = []
+ if request.collection_id:
+ collection = self.collection_list.get(request.collection_id)
+ if collection is None:
+ return response
+ action_ids = collection.action_ids
+ response.actions = self.action_list.to_ros_message(action_ids)
+ return response
+
+ def list_collections(self, request):
+ response = free_gait_msgs.srv.GetCollectionsResponse()
+ response.collections = self.collection_list.to_ros_message()
+ return response
+
+ def _execute_action_callback(self, goal):
+ self.action_sequence_queue = []
+ result = self.send_action(goal.action_id, False)
+ if result.status != result.RESULT_NOT_FOUND:
+ self.action.wait_for_state([ActionState.ERROR, ActionState.DONE])
+ result.status = result.RESULT_DONE
+ self.execute_action_server.set_succeeded(result)
+
+ def _send_action_callback(self, request):
+ self.action_sequence_queue = []
+ response = free_gait_msgs.srv.SendActionResponse()
+ response.result = self.send_action(request.goal.action_id, False)
+ return response
+
+ def _send_action_sequence_callback(self, request):
+ self.action_sequence_queue = []
+ for goal in request.goals:
+ self.action_sequence_queue.append(goal.action_id)
+ # Start first goal.
+ response = free_gait_msgs.srv.SendActionSequenceResponse()
+ response.result = self.send_action(self.action_sequence_queue[0], False)
+ self.action_sequence_queue.pop(0)
+ return response
+
+ def _preview_action_callback(self, request):
+ response = free_gait_msgs.srv.SendActionResponse()
+ response.result = self.send_action(request.goal.action_id, True)
+ return response
+
+ def send_action(self, action_id, use_preview):
+ self.reset()
+ if use_preview:
+ self.execute_steps_relay = self.preview_publisher
+ else:
+ self.execute_steps_relay = self.execute_steps_client
+
+ action_entry = self.action_list.get(action_id)
+ result = free_gait_msgs.msg.ExecuteActionResult()
+
+ if action_entry is None:
+ rospy.logerr('Action with id "' + action_id + '" does not exists.')
+ result.status = result.RESULT_NOT_FOUND
+ return result
+
+ if action_entry.file is None:
+ rospy.logerr('File for action with id "' + action_id + '" does not exists.')
+ result.status = result.RESULT_NOT_FOUND
+ return result
+
+ try:
+ if action_entry.type == ActionType.YAML:
+ self._load_yaml_action(action_entry.file)
+ if action_entry.type == ActionType.COMBINED_YAML:
+ self._load_combined_yaml_action(action_entry.file)
+ elif action_entry.type == ActionType.PYTHON:
+ self._load_python_action(action_entry.file)
+ elif action_entry.type == ActionType.LAUNCH:
+ self._load_launch_action(action_entry.file)
+
+ if self.action is None:
+ result.status = result.RESULT_UNKNOWN
+ rospy.logerr('An unkown state has been reached while reading the action.')
+ return result
+
+ if self.action.state == ActionState.ERROR or self.action.state == ActionState.UNINITIALIZED:
+ result.status = result.RESULT_FAILED
+ rospy.logerr('An error occurred while loading the action.')
+ return result
+
+ self.action.register_callback(self._action_feedback_callback, self._action_done_callback)
+ self.action.wait_for_state([ActionState.ERROR, ActionState.ACTIVE, ActionState.IDLE, ActionState.DONE])
+
+ if self.action.state == ActionState.ERROR:
+ result.status = result.RESULT_FAILED
+ rospy.logerr('An error occurred while initializing the action.')
+ else:
+ result.status = result.RESULT_STARTED
+ rospy.loginfo('Action was successfully started.')
+
+ except:
+ rospy.logerr('An exception occurred while loading the action.')
+ result.status = result.RESULT_FAILED
+ rospy.logerr(traceback.print_exc())
+
+ return result
+
+ def _load_yaml_action(self, file_path):
+ # Load action from YAML file.
+ rospy.loginfo('Loading Free Gait action from YAML file "' + file_path + '".')
+ goal = load_action_from_file(file_path)
+ rospy.logdebug(goal)
+ self.action = SimpleAction(self.execute_steps_relay, goal)
+ if goal is None:
+ rospy.logerr('Could not load action from YAML file.')
+ self.action.set_state(ActionState.ERROR)
+
+ def _load_combined_yaml_action(self, file_path):
+ # Load combined action from YAML file listing the combination of YAML actions.
+ rospy.loginfo('Loading Free Gait action from combined YAML file "' + file_path + '".')
+ self.action = CombinedYamlAction(self.execute_steps_relay)
+ self.action.set_goal_from_file(file_path)
+
+ def _load_python_action(self, file_path):
+ # Load action from Python script.
+ rospy.loginfo('Loading Free Gait action from Python script "' + file_path + '".')
+ # action_locals = dict()
+ # Kind of nasty, but currently only way to make external imports work.
+ execfile(file_path, globals(), globals())
+ self.action = action
+
+ def _load_launch_action(self, file_path):
+ # Load action with external launch file.
+ rospy.loginfo('Loading Free Gait action with launch file "' + file_path + '".')
+ self.action = LaunchAction(file_path, self.execute_steps_relay)
+
+ def _action_feedback_callback(self):
+ rospy.loginfo('Action switched to state: ' + ActionState.to_text(self.action.state) + '.')
+ if self.execute_action_server.is_active():
+ feedback = free_gait_msgs.msg.ExecuteActionFeedback()
+ feedback.status = self.action.state
+ self.execute_action_server.publish_feedback(feedback)
+
+ def _action_done_callback(self):
+ # If action sequence exists, continue with next action.
+ if len(self.action_sequence_queue) > 0:
+ thread.start_new_thread(self._load_next_action_in_sequence, ())
+ rospy.loginfo('Action switched to state: ' + ActionState.to_text(self.action.state) + '.')
+
+ def _load_next_action_in_sequence(self):
+ if self.action.state == ActionState.DONE:
+ result = self.send_action(self.action_sequence_queue[0], False)
+ self.action_sequence_queue.pop(0)
+ if (result.status == result.RESULT_STARTED):
+ return
+ # Error occured.
+ rospy.loginfo('Purging remaining actions from sequence.')
+ self.action_sequence_queue = []
+
+ def _check_and_start_action(self):
+ if self.action is not None:
+ if self.action.state == ActionState.INITIALIZED:
+ self.action.start()
+
+ def reset(self):
+ self.execute_steps_relay = None
+ try:
+ if self.action:
+ self.action.stop()
+ del self.action
+ self.action = None
+ # rospy.logwarn('Canceling action.')
+ except NameError:
+ rospy.logerr(traceback.print_exc())
+
+ def preempt(self):
+ self.reset()
+
+
+if __name__ == '__main__':
+ try:
+ rospy.init_node('free_gait_action_loader')
+ action_loader = ActionLoader()
+ rospy.loginfo('Ready to load actions from service call.')
+
+ updateRate = rospy.Rate(10)
+ while not rospy.is_shutdown():
+ # This is required for having the actions run in the main thread
+ # (instead through the thread by the service callback).
+ action_loader._check_and_start_action()
+ updateRate.sleep()
+
+ except rospy.ROSInterruptException:
+ # rospy.logerr(traceback.print_exc())
+ pass
diff --git a/free_gait_action_loader/package.xml b/free_gait_action_loader/package.xml
new file mode 100644
index 0000000..301520a
--- /dev/null
+++ b/free_gait_action_loader/package.xml
@@ -0,0 +1,17 @@
+
+
+ free_gait_action_loader
+ 0.3.0
+ Dynamic loading of Free Gait actions.
+ Peter Fankhauser
+ Peter Fankhauser
+ BSD
+ https://github.com/leggedrobotics/free_gait
+ https://github.com/leggedrobotics/free_gait/issues
+
+ catkin
+ rospy
+ free_gait_python
+ free_gait_msgs
+
+
diff --git a/free_gait_action_loader/setup.py b/free_gait_action_loader/setup.py
new file mode 100644
index 0000000..a6a6a91
--- /dev/null
+++ b/free_gait_action_loader/setup.py
@@ -0,0 +1,9 @@
+from distutils.core import setup
+from catkin_pkg.python_setup import generate_distutils_setup
+
+d = generate_distutils_setup(
+ packages=['free_gait_action_loader'],
+ package_dir={'': 'src'}
+)
+
+setup(**d)
diff --git a/free_gait_action_loader/src/free_gait_action_loader/__init__.py b/free_gait_action_loader/src/free_gait_action_loader/__init__.py
new file mode 100644
index 0000000..bcfc8bb
--- /dev/null
+++ b/free_gait_action_loader/src/free_gait_action_loader/__init__.py
@@ -0,0 +1,5 @@
+from action_handling import ActionType
+from action_handling import ActionEntry
+from action_handling import ActionList
+from collection_handling import Collection
+from collection_handling import CollectionList
diff --git a/free_gait_action_loader/src/free_gait_action_loader/action_handling.py b/free_gait_action_loader/src/free_gait_action_loader/action_handling.py
new file mode 100644
index 0000000..331dfeb
--- /dev/null
+++ b/free_gait_action_loader/src/free_gait_action_loader/action_handling.py
@@ -0,0 +1,150 @@
+#! /usr/bin/env python
+
+import os
+import rospy
+import roslib
+import rospkg
+from rosparam import load_file
+from os.path import *
+import free_gait_msgs.msg
+
+class ActionType:
+ YAML = 0
+ COMBINED_YAML = 1
+ PYTHON = 2
+ LAUNCH = 3
+
+ @staticmethod
+ def to_text(action_type):
+ if action_type == ActionType.YAML:
+ return 'yaml'
+ elif action_type == ActionType.COMBINED_YAML:
+ return 'combined_yaml'
+ elif action_type == ActionType.PYTHON:
+ return 'python'
+ elif action_type == ActionType.LAUNCH:
+ return 'launch'
+ else:
+ return None
+
+ @staticmethod
+ def from_text(action_type):
+ if action_type == 'yaml':
+ return ActionType.YAML
+ elif action_type == 'combined_yaml':
+ return ActionType.COMBINED_YAML
+ elif action_type == 'python':
+ return ActionType.PYTHON
+ elif action_type == 'launch':
+ return ActionType.LAUNCH
+ else:
+ return None
+
+
+class ActionEntry:
+
+ def __init__(self, package_path, parameters):
+ self.id = None
+ self.name = None
+ self.file = None
+ self.type = None
+ self.description = None
+ self.directory = None
+ self._initialize(package_path, parameters);
+
+ def __str__(self):
+ output = 'ID: ' + self.id
+ if self.name:
+ output = output + ", Name: " + self.name
+ if self.file:
+ output = output + ", File: " + self.file
+ if self.file:
+ output = output + ", Type: " + ActionType.to_text(self.type)
+ return output
+
+ def _initialize(self, package_path, parameters):
+ if 'id' in parameters:
+ self.id = parameters['id']
+ if 'name' in parameters:
+ self.name = parameters['name']
+ if 'file' in parameters:
+ self.file = abspath(join(package_path, parameters['file']))
+ if 'type' in parameters:
+ self.type = ActionType.from_text(parameters['type'])
+ if 'description' in parameters:
+ self.description = parameters['description']
+ self.directory = dirname(abspath(self.file))
+
+ def to_ros_message(self):
+ message = free_gait_msgs.msg.ActionDescription()
+ message.id = self.id
+ message.name = self.name
+ message.file = self.file
+ message.type = ActionType.to_text(self.type)
+ message.description = self.description
+ return message
+
+
+class ActionList:
+
+ def __init__(self, name):
+ self.name = name
+ self.actions = []
+
+ def update(self):
+ self.actions = []
+ rospack = rospkg.RosPack()
+ packages = rospack.get_depends_on(self.name, implicit=False)
+ rospy.loginfo(packages)
+ for package in packages:
+ rospy.loginfo(package)
+ manifest = rospack.get_manifest(package)
+ file_path = manifest.get_export(self.name, 'actions')
+ if not file_path:
+ continue
+ elif len(file_path) != 1:
+ rospy.logwarn("Cannot load actions [%s]: invalid 'actions' attribute."%(pkg))
+ continue
+
+ file_path = file_path[0]
+ try:
+ if not os.path.isfile(file_path):
+ rospy.logwarn('Actions parameter file with path "' + file_path + '" does not exists.')
+ continue
+
+ package_path = rospack.get_path(package)
+ parameters = load_file(file_path)
+ for action_parameters in parameters[0][0]['actions']:
+ entry = ActionEntry(package_path, action_parameters['action'])
+ self.actions.append(entry)
+
+ except Exception:
+ rospy.logwarn("Unable to load actions [%s] from package [%s]."%(file_path, package))
+
+ self.actions = sorted(self.actions, key = lambda x: (x.id))
+ return True
+
+ def get(self, id):
+ entry = [ e for e in self.actions if (e.id == id) ]
+ if len(entry) == 0:
+ return None
+ return entry[0]
+
+ def get_multiple(self, ids):
+ entries = []
+ for id in ids:
+ entry = self.get(id)
+ if entry:
+ entries.append(entry)
+ return entries
+
+ def to_ros_message(self, ids = []):
+ actions = []
+ if len(ids):
+ actions = self.get_multiple(ids)
+ else:
+ actions = self.actions
+ message = []
+ for action in actions:
+ message.append(action.to_ros_message())
+ return message
diff --git a/free_gait_action_loader/src/free_gait_action_loader/action_handling.pyc b/free_gait_action_loader/src/free_gait_action_loader/action_handling.pyc
new file mode 100644
index 0000000..f5a41c4
Binary files /dev/null and b/free_gait_action_loader/src/free_gait_action_loader/action_handling.pyc differ
diff --git a/free_gait_action_loader/src/free_gait_action_loader/collection_handling.py b/free_gait_action_loader/src/free_gait_action_loader/collection_handling.py
new file mode 100644
index 0000000..2ca346d
--- /dev/null
+++ b/free_gait_action_loader/src/free_gait_action_loader/collection_handling.py
@@ -0,0 +1,130 @@
+#! /usr/bin/env python
+
+import os
+import rospy
+import roslib
+import rospkg
+from rosparam import load_file
+from os.path import *
+import free_gait_msgs.msg
+
+
+class Collection:
+
+ def __init__(self, parameters):
+ self.id = None
+ self.name = None
+ self.action_ids = []
+ self.is_sequence = None
+ self._initialize(parameters)
+
+ def __str__(self):
+ output = 'ID: ' + self.id
+ if self.name:
+ output = output + ", Name: " + self.name
+ if self.action_ids:
+ output = output + ", Action IDs: "
+ for action_id in self.action_ids:
+ output = output + ", " + action_id
+ return output
+
+ def _initialize(self, parameters):
+ if 'id' in parameters:
+ self.id = parameters['id']
+ if 'name' in parameters:
+ self.name = parameters['name']
+ if 'actions' in parameters:
+ for action_id in parameters['actions']:
+ self.action_ids.append(action_id)
+ self.is_sequence = False
+ if 'is_sequence' in parameters:
+ if parameters['is_sequence']:
+ self.is_sequence = True
+ if not self.is_sequence:
+ self.action_ids = sorted(self.action_ids)
+
+ def to_ros_message(self):
+ message = free_gait_msgs.msg.CollectionDescription()
+ message.id = self.id
+ message.name = self.name
+ for action_id in self.action_ids:
+ message.action_ids.append(action_id)
+ message.is_sequence = self.is_sequence
+ return message
+
+
+class CollectionList:
+
+ def __init__(self, name):
+ self.name = name
+ self.collections = []
+ self.collections_to_merge = []
+ self.collections_to_ignore = []
+
+ def update(self):
+ self.collections = []
+ self.collections_to_merge = []
+ self.collections_to_ignore = []
+ rospack = rospkg.RosPack()
+ packages = rospack.get_depends_on(self.name, implicit=False)
+ for package in packages:
+ manifest = rospack.get_manifest(package)
+ file_path = manifest.get_export(self.name, 'collections')
+ if not file_path:
+ continue
+ elif len(file_path) != 1:
+ rospy.logwarn("Cannot load collections [%s]: invalid 'collections' attribute."%(pkg))
+ continue
+
+ file_path = file_path[0]
+ try:
+ if not os.path.isfile(file_path):
+ rospy.logwarn('Collections parameter file with path "' + file_path + '" does not exists.')
+ continue
+
+ parameters = load_file(file_path)
+ for collections_parameters in parameters[0][0]['collections']:
+ if 'collection' in collections_parameters:
+ collection = Collection(collections_parameters['collection'])
+ self.collections.append(collection)
+ elif 'add_to_collection' in collections_parameters:
+ collection = Collection(collections_parameters['add_to_collection'])
+ self.collections_to_merge.append(collection)
+ elif 'ignore_collection' in collections_parameters:
+ collection = Collection(collections_parameters['ignore_collection'])
+ self.collections_to_ignore.append(collection)
+
+ except Exception:
+ rospy.logwarn("Unable to load collections [%s] from package [%s]."%(file_path, package))
+
+ self._merge_collections()
+ self._ignore_collections()
+ self.collections = sorted(self.collections, key = lambda x: (x.id))
+ return True
+
+ def get(self, id):
+ collection = [ c for c in self.collections if (c.id == id) ]
+ if len(collection) == 0:
+ return None
+ return collection[0]
+
+ def remove(self, id):
+ self.collections[:] = [c for c in self.collections if (c.id != id) ]
+
+ def to_ros_message(self):
+ message = []
+ for collection in self.collections:
+ message.append(collection.to_ros_message())
+ return message
+
+ def _merge_collections(self):
+ for collection_to_merge in self.collections_to_merge:
+ collection = self.get(collection_to_merge.id)
+ if not collection:
+ rospy.logwarn('Could not find collection with id "%s" to add actions to.'%(collection_to_merge.id))
+ continue
+ collection.action_ids.extend(collection_to_merge.action_ids)
+
+ def _ignore_collections(self):
+ for collection_to_ignore in self.collections_to_ignore:
+ self.remove(collection_to_ignore.id)
diff --git a/free_gait_action_loader/src/free_gait_action_loader/collection_handling.pyc b/free_gait_action_loader/src/free_gait_action_loader/collection_handling.pyc
new file mode 100644
index 0000000..3baf1f7
Binary files /dev/null and b/free_gait_action_loader/src/free_gait_action_loader/collection_handling.pyc differ
diff --git a/free_gait_core/CMakeLists.txt b/free_gait_core/CMakeLists.txt
index 7232da2..44fe48b 100644
--- a/free_gait_core/CMakeLists.txt
+++ b/free_gait_core/CMakeLists.txt
@@ -5,10 +5,11 @@ set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
## Find catkin macros and libraries
find_package(catkin REQUIRED COMPONENTS
- #quadruped_model
+ quadruped_model
#numopt_common
#numopt_quadprog
#numopt_sqp
+ qp_solver
curves
grid_map_core
#robot_utils
@@ -35,13 +36,13 @@ catkin_package(
LIBRARIES
${PROJECT_NAME}
CATKIN_DEPENDS
- quadruped_model
- numopt_common
- numopt_quadprog
- numopt_sqp
+ #quadruped_model
+ #numopt_common
+ #numopt_quadprog
+ #numopt_sqp
curves
grid_map_core
- robot_utils
+ #robot_utils
std_utils
message_logger
)
@@ -98,7 +99,7 @@ add_library(${PROJECT_NAME}
src/pose_optimization/PoseOptimizationGeometric.cpp
src/pose_optimization/PoseOptimizationQP.cpp
src/pose_optimization/PoseOptimizationSQP.cpp
- src/pose_optimization/PoseParameterization.cpp
+ src/pose_optimization/poseparameterization.cpp
src/pose_optimization/PoseOptimizationObjectiveFunction.cpp
src/pose_optimization/PoseOptimizationFunctionConstraints.cpp
src/pose_optimization/PoseOptimizationProblem.cpp
diff --git a/free_gait_core/include/free_gait_core/TypeDefs.hpp b/free_gait_core/include/free_gait_core/TypeDefs.hpp
index 91125fc..f1cb7cf 100644
--- a/free_gait_core/include/free_gait_core/TypeDefs.hpp
+++ b/free_gait_core/include/free_gait_core/TypeDefs.hpp
@@ -21,14 +21,14 @@
namespace free_gait {
-struct EnumClassHash
-{
- template
- std::size_t operator()(T t) const
- {
- return static_cast(t);
- }
-};
+//struct EnumClassHash
+//{
+// template
+// std::size_t operator()(T t) const
+// {
+// return static_cast(t);
+// }
+//};
// Import enum aliases.
using QD = quadruped_model::QuadrupedModel::QuadrupedDescription;
diff --git a/free_gait_core/include/free_gait_core/executor/AdapterBase.hpp b/free_gait_core/include/free_gait_core/executor/AdapterBase.hpp
index d47fba2..8898c74 100644
--- a/free_gait_core/include/free_gait_core/executor/AdapterBase.hpp
+++ b/free_gait_core/include/free_gait_core/executor/AdapterBase.hpp
@@ -109,11 +109,12 @@ class AdapterBase
const LimbEnum& limb, const LinearAcceleration& endEffectorLinearAccelerationInWorldFrame) const = 0;
//! Hook to write data to internal robot representation from state.
- virtual bool setInternalDataFromState(const State& state) const = 0;
-// virtual bool setInternalDataFromState(const State& state, bool updateContacts = true, bool updatePosition = true,
-// bool updateVelocity = true, bool updateAcceleration = false) const = 0;
-// virtual void createCopyOfState() const = 0;
-// virtual void resetToCopyOfState() const = 0;
+// virtual bool setInternalDataFromState(const State& state) const = 0;
+ virtual bool setInternalDataFromState(const State& state, bool updateContacts = true, bool updatePosition = true,
+ bool updateVelocity = true, bool updateAcceleration = false) const = 0;
+ virtual void createCopyOfState() const = 0;
+ virtual void resetToCopyOfState() const = 0;
+ virtual const State& getState() const = 0;
};
} /* namespace free_gait */
diff --git a/free_gait_core/include/free_gait_core/executor/State.hpp b/free_gait_core/include/free_gait_core/executor/State.hpp
index 06199d2..a8e04ea 100644
--- a/free_gait_core/include/free_gait_core/executor/State.hpp
+++ b/free_gait_core/include/free_gait_core/executor/State.hpp
@@ -10,6 +10,7 @@
#include "free_gait_core/TypeDefs.hpp"
//#include
+#include "quadruped_model/quadruped_state.h"
#include
// STD
@@ -24,7 +25,7 @@ namespace free_gait {
class State : public quadruped_model::QuadrupedState
{
public:
-// using QD = quadruped_model::QuadrupedModel::QuadrupedDescription;
+ using QD = quadruped_model::QuadrupedModel::QuadrupedDescription;
State();
virtual ~State();
@@ -80,7 +81,8 @@ class State : public quadruped_model::QuadrupedState
void setEmptyControlSetup(const LimbEnum& limb);
void getAllJointNames(std::vector& jointNames) const;
-
+ Position getSupportFootPosition(const LimbEnum& limb);
+ void setSupportFootStance(const Stance& footInSupport);
friend std::ostream& operator << (std::ostream& out, const State& state);
private:
@@ -100,6 +102,8 @@ class State : public quadruped_model::QuadrupedState
std::unordered_map surfaceNormals_;
bool robotExecutionStatus_;
std::string stepId_; // empty if undefined.
+
+ Stance footHoldInSupport_;
};
} /* namespace */
diff --git a/free_gait_core/include/free_gait_core/pose_optimization/PoseOptimizationFunctionConstraints.hpp b/free_gait_core/include/free_gait_core/pose_optimization/PoseOptimizationFunctionConstraints.hpp
index 48dce51..bdf8b20 100644
--- a/free_gait_core/include/free_gait_core/pose_optimization/PoseOptimizationFunctionConstraints.hpp
+++ b/free_gait_core/include/free_gait_core/pose_optimization/PoseOptimizationFunctionConstraints.hpp
@@ -12,15 +12,16 @@
#include "free_gait_core/executor/AdapterBase.hpp"
#include "free_gait_core/executor/State.hpp"
#include "free_gait_core/pose_optimization/PoseConstraintsChecker.hpp"
-
-#include
+#include "qp_solver/quadraticproblemsolver.h"
+#include "free_gait_core/pose_optimization/poseparameterization.h"
+//#include
#include
#include