Я использую ROS или ZMQ в Unity для связи со своим устройством и хочу, чтобы мой код можно было адаптировать к обоим методам без необходимости рефакторинга всего моего кода. Затем я создал класс интерфейса, который обеспечивает связь между моим основным кодом и коммуникационной библиотекой. Однако при подписке на тему ROS мне нужно использовать функцию обратного вызова для получения данных. Но мой обратный вызов никогда не вызывается, и когда я проверяю цель делегата, она равна нулю, даже если я указал это при создании.
Вот основной класс , который определяет подписчика и запрашивает создание интерфейса. Я помещаю с комментариями результаты каждой команды отладки. Поскольку тип сообщений в ROS и ZMQ различается, я использую псевдоним, определенный для ROS следующим образом: public override Type TypeFloatArrayAlias { get; } = typeof(Float32MultiArrayMsg);.
// ... (class RobotCommand)
try
{
var defineSubscriberMethod = m_interface.GetType().GetMethod("DefineSubscriber");
var genericMethod = defineSubscriberMethod.MakeGenericMethod(m_interface.TypeFloatArrayAlias);
var delegateType = typeof(Action).MakeGenericType(m_interface.TypeFloatArrayAlias);
var methodInfo = this.GetType().GetMethod(nameof(UpdateVirtualRobotJointsCallback),
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (methodInfo == null)
throw new Exception("Method 'UpdateVirtualRobotJointsCallback' not found.");
Debug.Log($"Method Info: {methodInfo.Name} Target: {this.GetType().Name}");
// Method Info: UpdateVirtualRobotJointsCallback Target: RobotCommand
Delegate callbackDelegate = Delegate.CreateDelegate(delegateType, this, methodInfo);
Debug.Log($"Delegate Target: {callbackDelegate.Target}, Method: {callbackDelegate.Method}");
// Delegate Target: null, Method: Void UpdateVirtualRobotJointsCallback(RosMessageTypes.Std.Float32MultiArrayMsg)
genericMethod.Invoke(m_interface, new object[]
{
Const.ROS_NAMESPACE + "robot_joint_values",
callbackDelegate
});
}
catch (Exception e)
{
Debug.LogError($"Error invoking DefineSubscriber: {e.Message}");
}
}
public void UpdateVirtualRobotJointsCallback(Float32MultiArrayMsg msg)
{
Debug.Log("called");
StartCoroutine(m_controller.MoveRobot_Coroutine(m_interface.ToFloatArray(msg)));
}
Вот метод DefineSubscriber интерфейса:
public override void DefineSubscriber(string topic, Action callback)
{
try
{
Debug.Log($"Delegate Callback: Target={callback.Target}, Method={callback.Method}");
// Delegate Callback: Target=null, Method=Void UpdateVirtualRobotJointsCallback(RosMessageTypes.Std.Float32MultiArrayMsg)
Type msgType = typeof(T);
// _node is the ROS object (ROSConnection.GetOrCreateInstance())
var subscribeMethod = _node.GetType().GetMethod("Subscribe").MakeGenericMethod(msgType);
subscribeMethod.Invoke(_node, new object[] { topic, callback });
_subscriberList[topic] = (x => callback((T)x), msgType);
Debug.Log($"Subscriber created for topic: {topic} with message type: {msgType.Name}");
}
catch (Exception e)
{
Debug.LogError($"Error while defining subscriber for topic {topic}: {e.Message}");
}
}
Я не понимаю, почему цель моего обратного вызова равна нулю. Думаю, именно поэтому он никогда не вызывается, поскольку не связан с объектом.
К вашему сведению, вот рабочее творение подписчика:
void Start()
{
ROSConnection.GetOrCreateInstance().Subscribe(m_topicName, UpdateVirtualRobotJointsCallback);
}
// Update is called once per frame
void Update()
{
}
void UpdateVirtualRobotJointsCallback(Float32MultiArrayMsg msg)
{
Debug.Log("called");
StartCoroutine(xarmController.MoveRobot_Coroutine(new List(msg.data)));
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... ull-target
У делегата моей функции пустая цель ⇐ C#
Место общения программистов C#
1728367103
Anonymous
Я использую ROS или ZMQ в Unity для связи со своим устройством и хочу, чтобы мой код можно было адаптировать к обоим методам без необходимости рефакторинга всего моего кода. Затем я создал класс интерфейса, который обеспечивает связь между моим основным кодом и коммуникационной библиотекой. Однако при подписке на тему ROS мне нужно использовать функцию обратного вызова для получения данных. Но мой обратный вызов никогда не вызывается, и когда я проверяю цель делегата, она равна нулю, даже если я указал это при создании.
Вот основной класс , который определяет подписчика и запрашивает создание интерфейса. Я помещаю с комментариями результаты каждой команды отладки. Поскольку тип сообщений в ROS и ZMQ различается, я использую псевдоним, определенный для ROS следующим образом: public override Type TypeFloatArrayAlias { get; } = typeof(Float32MultiArrayMsg);.
// ... (class RobotCommand)
try
{
var defineSubscriberMethod = m_interface.GetType().GetMethod("DefineSubscriber");
var genericMethod = defineSubscriberMethod.MakeGenericMethod(m_interface.TypeFloatArrayAlias);
var delegateType = typeof(Action).MakeGenericType(m_interface.TypeFloatArrayAlias);
var methodInfo = this.GetType().GetMethod(nameof(UpdateVirtualRobotJointsCallback),
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (methodInfo == null)
throw new Exception("Method 'UpdateVirtualRobotJointsCallback' not found.");
Debug.Log($"Method Info: {methodInfo.Name} Target: {this.GetType().Name}");
// Method Info: UpdateVirtualRobotJointsCallback Target: RobotCommand
Delegate callbackDelegate = Delegate.CreateDelegate(delegateType, this, methodInfo);
Debug.Log($"Delegate Target: {callbackDelegate.Target}, Method: {callbackDelegate.Method}");
// Delegate Target: null, Method: Void UpdateVirtualRobotJointsCallback(RosMessageTypes.Std.Float32MultiArrayMsg)
genericMethod.Invoke(m_interface, new object[]
{
Const.ROS_NAMESPACE + "robot_joint_values",
callbackDelegate
});
}
catch (Exception e)
{
Debug.LogError($"Error invoking DefineSubscriber: {e.Message}");
}
}
public void UpdateVirtualRobotJointsCallback(Float32MultiArrayMsg msg)
{
Debug.Log("called");
StartCoroutine(m_controller.MoveRobot_Coroutine(m_interface.ToFloatArray(msg)));
}
Вот метод DefineSubscriber интерфейса:
public override void DefineSubscriber(string topic, Action callback)
{
try
{
Debug.Log($"Delegate Callback: Target={callback.Target}, Method={callback.Method}");
// Delegate Callback: Target=null, Method=Void UpdateVirtualRobotJointsCallback(RosMessageTypes.Std.Float32MultiArrayMsg)
Type msgType = typeof(T);
// _node is the ROS object (ROSConnection.GetOrCreateInstance())
var subscribeMethod = _node.GetType().GetMethod("Subscribe").MakeGenericMethod(msgType);
subscribeMethod.Invoke(_node, new object[] { topic, callback });
_subscriberList[topic] = (x => callback((T)x), msgType);
Debug.Log($"Subscriber created for topic: {topic} with message type: {msgType.Name}");
}
catch (Exception e)
{
Debug.LogError($"Error while defining subscriber for topic {topic}: {e.Message}");
}
}
Я не понимаю, почему цель моего обратного вызова равна нулю. Думаю, именно поэтому он никогда не вызывается, поскольку не связан с объектом.
К вашему сведению, вот рабочее творение подписчика:
void Start()
{
ROSConnection.GetOrCreateInstance().Subscribe(m_topicName, UpdateVirtualRobotJointsCallback);
}
// Update is called once per frame
void Update()
{
}
void UpdateVirtualRobotJointsCallback(Float32MultiArrayMsg msg)
{
Debug.Log("called");
StartCoroutine(xarmController.MoveRobot_Coroutine(new List(msg.data)));
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79064501/delegate-of-my-function-has-a-null-target[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия