From c761640114e1797cf1685765556dcef3915754c0 Mon Sep 17 00:00:00 2001
From: Felix Agner <felix.agner@control.lth.se>
Date: Sat, 29 Oct 2022 15:32:13 +0200
Subject: [PATCH] Added a new, cleaner framework for the servers that I want to
 work into a proper python package

---
 code/src/omnibot_package/CrazyFlieLogger.py | 124 ++++++++++++++++++++
 code/src/omnibot_package/__init__.py        |   2 +
 2 files changed, 126 insertions(+)
 create mode 100644 code/src/omnibot_package/CrazyFlieLogger.py
 create mode 100644 code/src/omnibot_package/__init__.py

diff --git a/code/src/omnibot_package/CrazyFlieLogger.py b/code/src/omnibot_package/CrazyFlieLogger.py
new file mode 100644
index 0000000..aa449c3
--- /dev/null
+++ b/code/src/omnibot_package/CrazyFlieLogger.py
@@ -0,0 +1,124 @@
+# numpy
+import numpy as np
+
+# Crazyflie packages
+from cflib.crazyflie import Crazyflie
+from cflib.crazyflie.log import LogConfig
+
+
+class CrazyFlieLogger:
+    
+    """
+    Simple logging class that logs the Crazyflie Stabilizer from a supplied
+    link uri
+    """
+    # Define which states to log:
+    namelink = {'stateEstimate.x': 0, 'stateEstimate.y': 1,'stateEstimate.z': 2, 'stabilizer.yaw':3}
+    #_Offset for crazyflie position on robot to center
+    position_offset = 0.11
+
+    def __init__(self, link_uri):
+        """ Initialize and run the example with the specified link_uri """
+
+        self._cf = Crazyflie(rw_cache='./cache')
+        self._state = np.array([0.0,0.0,0.0,0.0])
+
+        # Connect some callbacks from the Crazyflie API
+        self._cf.connected.add_callback(self._connected)
+        self._cf.disconnected.add_callback(self._disconnected)
+        self._cf.connection_failed.add_callback(self._connection_failed)
+        self._cf.connection_lost.add_callback(self._connection_lost)
+
+        print('Connecting to %s' % link_uri)
+
+        # Try to connect to the Crazyflie
+        self._cf.open_link(link_uri)
+
+        # Variable used to keep main loop occupied until disconnect
+        self.is_connected = True
+
+    def _connected(self, link_uri):
+        """ This callback is called form the Crazyflie API when a Crazyflie
+        has been connected and the TOCs have been downloaded."""
+        print('Connected to %s' % link_uri)
+
+        # The definition of the logconfig can be made before connecting
+        self._lg_stab = LogConfig(name='Stabilizer', period_in_ms=100)
+        self._lg_stab.add_variable('stateEstimate.x', 'float')
+        self._lg_stab.add_variable('stateEstimate.y', 'float')
+        self._lg_stab.add_variable('stateEstimate.z', 'float')
+        self._lg_stab.add_variable('stabilizer.yaw', 'float')
+        
+        # The fetch-as argument can be set to FP16 to save space in the log packet
+        #self._lg_stab.add_variable('pm.vbat', 'FP16')
+
+        # Adding the configuration cannot be done until a Crazyflie is
+        # connected, since we need to check that the variables we
+        # would like to log are in the TOC.
+        try:
+            self._cf.log.add_config(self._lg_stab)
+            # This callback will receive the data
+            self._lg_stab.data_received_cb.add_callback(self._stab_log_data)
+            # This callback will be called on errors
+            self._lg_stab.error_cb.add_callback(self._stab_log_error)
+            # Start the logging
+            self._lg_stab.start()
+        except KeyError as e:
+            print('Could not start log configuration,'
+                  '{} not found in TOC'.format(str(e)))
+        except AttributeError:
+            print('Could not add Stabilizer log config, bad configuration.')
+
+
+    def _stab_log_error(self, logconf, msg):
+        """Callback from the log API when an error occurs"""
+        print('Error when logging %s: %s' % (logconf.name, msg))
+
+    def _stab_log_data(self, timestamp, data, logconf):
+        """Callback from a the log API when data arrives"""
+        #print(f'[{timestamp}][{logconf.name}]: ', end='')
+        for name, value in data.items():
+            self._state[self._namelink[name]] = value
+            #print(f'{name}: {value:3.3f} ', end='\n')
+        #print()
+
+    def _connection_failed(self, link_uri, msg):
+        """Callback when connection initial connection fails (i.e no Crazyflie
+        at the specified address)"""
+        print('Connection to %s failed: %s' % (link_uri, msg))
+        self.is_connected = False
+
+    def _connection_lost(self, link_uri, msg):
+        """Callback when disconnected after a connection has been made (i.e
+        Crazyflie moves out of range)"""
+        print('Connection to %s lost: %s' % (link_uri, msg))
+
+    def _disconnected(self, link_uri):
+        """Callback when the Crazyflie is disconnected (called in all cases)"""
+        print('Disconnected from %s' % link_uri)
+        self.is_connected = False
+        
+    def x(self):
+        """ Return x-position of robot center"""
+		# Note that the offset of the crazyflie mount position is included
+        return self._state[0] - np.sin(np.deg2rad(self._state[3]))*self._position_offset 
+    
+    def y(self):
+        """ Return y-position of robot center"""
+		# Note that the offset of the crazyflie mount position is included
+        return self._state[1] + np.cos(np.deg2rad(self._state[3]))*self._position_offset 
+    
+    def z(self):
+        """ Return z-position of robot center"""
+        return self._state[2]
+    
+    def theta(self):
+        """ Return direction of robot center, measured in radians between -pi and pi."""
+		# Note that the offset of the crazyflie mount position is included
+        return np.mod(self._state[3]*np.pi/180 + 11*np.pi/6,2*np.pi)-np.pi
+    
+    def states(self):
+        return self._state
+    
+    def close(self):
+        self._cf.close_link()
diff --git a/code/src/omnibot_package/__init__.py b/code/src/omnibot_package/__init__.py
new file mode 100644
index 0000000..14410f4
--- /dev/null
+++ b/code/src/omnibot_package/__init__.py
@@ -0,0 +1,2 @@
+from . import crazyflie_logger
+from . import Omnibot
-- 
GitLab