Compare commits

...
2 changed files with 103 additions and 65 deletions

No files matched your search

@@ -28,6 +28,7 @@ use ethercat_hal::helpers::ethercrab_types::{
EthercrabSubDeviceOperational, EthercrabSubDevicePreoperational,
};
use ethercrab::MainDevice;
use ethercrab::SubDeviceGroup;
use ethercrab::SubDeviceIdentity;
use crate::machines::identification::DeviceMachineIdentification;
@@ -68,11 +69,11 @@ impl Default for MachineIdentificationAddresses {
///
/// Returns a vector of MachineDeviceIdentification for all subdevices
pub async fn read_device_identifications<'maindevice>(
subdevices: &Vec<EthercrabSubDevicePreoperational<'maindevice>>,
group: &SubDeviceGroup<16, 256>,
maindevice: &MainDevice<'maindevice>,
) -> Vec<Result<DeviceMachineIdentification, Error>> {
let mut result = Vec::new();
for subdevice in subdevices.iter() {
for subdevice in group.iter(maindevice) {
let identification = machine_device_identification(&subdevice, maindevice).await;
result.push(identification);
}
+100 -63
View File
@@ -15,13 +15,78 @@ use control_core::machines::identification::{
use control_core::machines::new::MachineNewHardwareEthercat;
use control_core::realtime::{set_core_affinity, set_realtime_priority};
use control_core::socketio::namespace::NamespaceCacheingLogic;
use ethercat_hal::devices::devices_from_subdevices;
use ethercat_hal::devices::{EthercatDevice, devices_from_subdevices};
use ethercrab::std::{ethercat_now, tx_rx_task};
use ethercrab::{MainDevice, MainDeviceConfig, PduStorage, RetryBehaviour, Timeouts};
use ethercrab::{
MainDevice, MainDeviceConfig, PduStorage, RetryBehaviour, SubDeviceGroup, SubDeviceRef,
Timeouts,
};
use smol::channel::Sender;
use smol::lock::RwLock;
use std::{sync::Arc, time::Duration};
pub async fn get_subdevices<'a>(
subdevice_group: &'a SubDeviceGroup<16, 256>,
maindevice: &'a MainDevice<'a>,
) -> Vec<SubDeviceRef<'a, &'a ethercrab::SubDevice>> {
return subdevice_group.iter(&maindevice).collect();
}
pub async fn extract_ident_tuple(
device_identifications: Vec<DeviceIdentification>,
maindevice: &MainDevice<'_>,
group_preop: &SubDeviceGroup<16, 256>,
devices: Vec<Arc<smol::lock::RwLock<dyn EthercatDevice>>>,
) -> (
Vec<DeviceIdentification>,
Vec<Arc<smol::lock::RwLock<(dyn EthercatDevice + 'static)>>>,
) {
let group = &*group_preop;
let devices: Vec<_> = device_identifications
.into_iter()
.zip(devices)
.zip(group.iter(&maindevice))
.map(|((a, b), c)| (a, b, c))
.collect();
// filter devices and if Option<DeviceMachineIdentification> is Some
// return identified_devices, identified_device_identifications, identified_subdevices
let (identified_device_identifications, identified_devices, _): (
Vec<_>,
Vec<_>,
Vec<_>,
) = devices
.iter()
.filter(|(device_identification, _, _)| {
match device_identification {
DeviceIdentification {
device_machine_identification: Some(_),
..
} => true,
_ => false
}
})
.map(|(device_identification, device, subdevice)| {
(
device_identification.clone(),
device.clone(),
subdevice,
)
})
.fold(
(Vec::new(), Vec::new(), Vec::new()),
|mut acc, (identified_device_identification, identified_device, identified_subdevice)| {
acc.0.push(identified_device_identification);
acc.1.push(identified_device);
acc.2.push(identified_subdevice);
acc
},
);
return (identified_device_identifications, identified_devices);
}
pub async fn setup_loop(
thread_panic_tx: Sender<PanicDetails>,
interface: &str,
@@ -118,12 +183,15 @@ pub async fn setup_loop(
};
// create devices
let devices =
let devices: Vec<Arc<smol::lock::RwLock<dyn EthercatDevice>>> =
devices_from_subdevices::<MAX_SUBDEVICES, PDI_LEN>(&mut group_preop, &maindevice)?;
let subdevices = group_preop.iter(&maindevice).collect::<Vec<_>>();
let mut subdevices: Vec<SubDeviceRef<'_, &ethercrab::SubDevice>> = Vec::new();
for dev in group_preop.iter(&maindevice) {
subdevices.push(dev);
}
// extract device identifications
let device_identifications = read_device_identifications(&subdevices, &maindevice)
let device_identifications = read_device_identifications(&group_preop, &maindevice)
.await
.into_iter()
.enumerate()
@@ -138,48 +206,15 @@ pub async fn setup_loop(
)
.collect::<Vec<_>>();
let devices = device_identifications
.into_iter()
.zip(devices)
.zip(&subdevices)
.map(|((a, b), c)| (a, b, c))
.collect::<Vec<_>>();
let (identified_device_identifications, identified_devices) =
extract_ident_tuple(device_identifications, &maindevice, &group_preop, devices).await;
// filter devices and if Option<DeviceMachineIdentification> is Some
// return identified_devices, identified_device_identifications, identified_subdevices
let (identified_device_identifications, identified_devices, identified_subdevices): (
Vec<_>,
Vec<_>,
Vec<_>,
) = devices
.iter()
.filter(|(device_identification, _, _)| {
match device_identification {
DeviceIdentification {
device_machine_identification: Some(_),
..
} => true,
_ => false
}
})
.map(|(device_identification, device, subdevice)| {
(
device_identification.clone(),
device.clone(),
*subdevice,
)
})
.fold(
(Vec::new(), Vec::new(), Vec::new()),
|mut acc, (identified_device_identification, identified_device, identified_subdevice)| {
acc.0.push(identified_device_identification);
acc.1.push(identified_device);
acc.2.push(identified_subdevice);
acc
},
);
let subdevice_values: Vec<SubDeviceRef<'_, &ethercrab::SubDevice>> =
group_preop.iter(&maindevice).collect();
let subdevice_refs: Vec<&SubDeviceRef<'_, &ethercrab::SubDevice>> =
subdevice_values.iter().collect();
// construct machines
{
let mut machines_guard = app_state.machines.write().await;
machines_guard.set_ethercat_devices::<MAX_SUBDEVICES, PDI_LEN>(
@@ -187,18 +222,27 @@ pub async fn setup_loop(
&MACHINE_REGISTRY,
&MachineNewHardwareEthercat {
ethercat_devices: &identified_devices,
subdevices: &identified_subdevices,
subdevices: &subdevice_refs,
},
app_state.socketio_setup.socket_queue_tx.clone(),
Arc::downgrade(&app_state.machines),
);
}
// remove subdevice from devices tuple
let devices = devices
.iter()
.map(|(device_identification, device, _)| (device_identification.clone(), device.clone()))
.collect::<Vec<_>>();
let group_pdi = group_preop.into_pre_op_pdi(&maindevice).await?;
// Put group in operational state
let group_op = match group_pdi.into_op(&maindevice).await {
Ok(group_op) => {
tracing::info!("Group in OP state");
group_op
}
Err(err) => Err(anyhow::anyhow!(
"[{}::setup_loop] Failed to put group in OP state: {:?}",
module_path!(),
err
))?,
};
// Notify client via socketio
let app_state_clone = app_state.clone();
@@ -213,18 +257,11 @@ pub async fn setup_loop(
main_namespace.emit(MainNamespaceEvents::MachinesEvent(event));
});
// Put group in operational state
let group_op = match group_preop.into_op(&maindevice).await {
Ok(group_op) => {
tracing::info!("Group in OP state");
group_op
}
Err(err) => Err(anyhow::anyhow!(
"[{}::setup_loop] Failed to put group in OP state: {:?}",
module_path!(),
err
))?,
};
let devices: Vec<(DeviceIdentification, Arc<RwLock<dyn EthercatDevice>>)> =
identified_device_identifications
.into_iter()
.zip(identified_devices.into_iter())
.collect();
// Write all this stuff to `app_state`
{